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?