XNA: Best way to download and read an XML file?

It is difficult for me to do this seemingly simple task. I want to load XML files with the same ease of loading art resources:

content = new ContentManager(Services); content.RootDirectory = "Content"; Texture2d background = content.Load<Texture2D>("images\\ice"); 

I am not sure how to do this. This tutorial seems useful, but how do I get an instance of StorageDevice ?

I now have something working, but it looks pretty hacky:

 public IDictionary<string, string> Get(string typeName) { IDictionary<String, String> result = new Dictionary<String, String>(); xmlReader.Read(); // get past the XML declaration string element = null; string text = null; while (xmlReader.Read()) { switch (xmlReader.NodeType) { case XmlNodeType.Element: element = xmlReader.Name; break; case XmlNodeType.Text: text = xmlReader.Value; break; } if (text != null && element != null) { result[element] = text; text = null; element = null; } } return result; } 

I apply this to the following XML file:

 <?xml version="1.0" encoding="utf-8" ?> <zombies> <zombie> <health>100</health> <positionX>23</positionX> <positionY>12</positionY> <speed>2</speed> </zombie> </zombies> 

And he can pass this unit test:

  internal virtual IPersistentState CreateIPersistentState(string fullpath) { IPersistentState target = new ReadWriteXML(File.Open(fullpath, FileMode.Open)); return target; } /// <summary> ///A test for Get with one zombie. ///</summary> //[TestMethod()] public void SimpleGetTest() { string fullPath = "C:\\pathTo\\Data\\SavedZombies.xml"; IPersistentState target = CreateIPersistentState(fullPath); string typeName = "zombie"; IDictionary<string, string> expected = new Dictionary<string, string>(); expected["health"] = "100"; expected["positionX"] = "23"; expected["positionY"] = "12"; expected["speed"] = "2"; IDictionary<string, string> actual = target.Get(typeName); foreach (KeyValuePair<string, string> entry in expected) { Assert.AreEqual(entry.Value, expected[entry.Key]); } } 

The drawbacks of the current approach are: file loading is poor, and matching keys with values ​​seems like more effort than necessary. Also, I suspect this approach will fall apart with more than one XML entry.

I can not imagine that this is an optimal implementation.

UPDATE . Following @Peter Lillevold's advice, I changed this a bit:

  public IDictionary<string, string> Get(string typeName) { IDictionary<String, String> result = new Dictionary<String, String>(); IEnumerable<XElement> zombieValues = root.Element(@typeName).Elements(); //result["health"] = zombie.Element("health").ToString(); IDictionary<string, XElement> nameToElement = zombieValues.ToDictionary(element => element.Name.ToString()); foreach (KeyValuePair<string, XElement> entry in nameToElement) { result[entry.Key] = entry.Value.FirstNode.ToString(); } return result; } public ReadWriteXML(string uri) { root = XElement.Load(uri); } internal virtual IPersistentState CreateIPersistentState(string fullpath) { return new ReadWriteXML(fullpath); } /// <summary> ///A test for Get with one zombie. ///</summary> [TestMethod()] public void SimpleGetTest() { IPersistentState target = CreateIPersistentState("../../../path/Data/SavedZombies.xml"); string typeName = "zombie"; IDictionary<string, string> expected = new Dictionary<string, string>(); expected["health"] = "100"; expected["positionX"] = "23"; expected["positionY"] = "12"; expected["speed"] = "2"; IDictionary<string, string> actual = target.Get(typeName); foreach (KeyValuePair<string, string> entry in expected) { Assert.AreEqual(entry.Value, actual[entry.Key]); } } 

The download is still pretty crappy, and somehow I couldn't get a single-line ToDictionary to work with these two lambdas. I had to resort to this foreach loop. What am I doing wrong there?

+7
c # xml xna
source share
2 answers

There is also a new and brilliant XElement (which shows Linq to XML ). This sample will load the xml file, search for zombies and upload the values ​​to the dictionary:

 var doc = XElement.Load("filename"); var zombieValues = doc.Element("zombie").Elements(); var zombieDictionary = zombieValues.ToDictionary( element => element.Name.ToString(), element => element.Value); 

If you prefer to explicitly select each value (and use a listing to automatically convert to the appropriate value types), you can do:

 var zombie = doc.Element("zombie"); var health = (int)zombie.Element("health"); var positionX = (int)zombie.Element("positionX"); var positionY = (int)zombie.Element("positionY"); var speed = (int)zombie.Element("speed"); 

Update: fixing some typos and clearing bits, your Get method should look like this:

 public IDictionary<string, string> Get(string typeName) { var zombie = root.Element(typeName); return zombie.Elements() .ToDictionary( element => element.Name.ToString(), element => element.Value); } 
+8
source share
 System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.LoadXml(xmlString); string health = doc["zombies"]["zombie"]["health"].InnerText; // etc.. // or looping foreach( XmlNode node in doc["zombies"].ChildNodes ) { string health = node["health"].InnerText; // etc... } 

Or does this not work in XNA?

+2
source share

All Articles