title: XNA: Best way to load and read a XML file?
body: <p>I'm having difficulty doing this seemingly simple task. I want to load XML files with the same ease of loading art assets:</p>
  
  <pre><code>        content  = new ContentManager(Services);
          content.RootDirectory = "Content";
          Texture2d background = content.Load&lt;Texture2D&gt;("images\\ice");
  </code></pre>
  
  <p>I'm not sure how to do this. This <a href="http://msdn.microsoft.com/en-us/library/bb203924%28v=XNAGameStudio.31%29.aspx" rel="noreferrer">tutorial</a> seems helpful, but how do I get a <code>StorageDevice</code> instance?</p>
  
  <p>I do have something working now, but it feels pretty hacky:</p>
  
  <pre><code>public IDictionary&lt;string, string&gt; Get(string typeName)
          {
              IDictionary&lt;String, String&gt; result = new Dictionary&lt;String, String&gt;();
              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 &amp;&amp; element != null)
                  {
                      result[element] = text;
                      text = null;
                      element = null;
                  }
  
              }
              return result;
          }
  </code></pre>
  
  <p>I apply this to the following XML file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8" ?&gt;
  &lt;zombies&gt;
    &lt;zombie&gt;
      &lt;health&gt;100&lt;/health&gt;
      &lt;positionX&gt;23&lt;/positionX&gt;
      &lt;positionY&gt;12&lt;/positionY&gt;
      &lt;speed&gt;2&lt;/speed&gt;
    &lt;/zombie&gt;
  &lt;/zombies&gt;
  </code></pre>
  
  <p>And it is able to pass this unit test:</p>
  
  <pre><code>    internal virtual IPersistentState CreateIPersistentState(string fullpath)
      {
          IPersistentState target = new ReadWriteXML(File.Open(fullpath, FileMode.Open));
          return target;
      }
  
      /// &lt;summary&gt;
      ///A test for Get with one zombie.
      ///&lt;/summary&gt;
      //[TestMethod()]
      public void SimpleGetTest()
      {
          string fullPath = "C:\\pathTo\\Data\\SavedZombies.xml";
          IPersistentState target = CreateIPersistentState(fullPath);
          string typeName = "zombie"; 
  
          IDictionary&lt;string, string&gt; expected = new Dictionary&lt;string, string&gt;();
          expected["health"] = "100";
          expected["positionX"] = "23";
          expected["positionY"] = "12";
          expected["speed"] = "2";
  
          IDictionary&lt;string, string&gt; actual = target.Get(typeName);
  
          foreach (KeyValuePair&lt;string, string&gt; entry in expected)
          {
              Assert.AreEqual(entry.Value, expected[entry.Key]);
          }
      }
  </code></pre>
  
  <p>Downsides to the current approach: file loading is done poorly, and matching keys to values seems like it's way more effort than necessary. Also, I suspect this approach would fall apart with more than one entry in the XML.</p>
  
  <p>I can't imagine that this is the optimal implementation.</p>
  
  <p><strong>UPDATE</strong>: Following the advice of @Peter Lillevold, I've changed this a bit:</p>
  
  <pre><code>    public IDictionary&lt;string, string&gt; Get(string typeName)
      {
          IDictionary&lt;String, String&gt; result = new Dictionary&lt;String, String&gt;();
  
          IEnumerable&lt;XElement&gt; zombieValues = root.Element(@typeName).Elements();
  
          //result["health"] = zombie.Element("health").ToString();
  
          IDictionary&lt;string, XElement&gt; nameToElement = zombieValues.ToDictionary(element =&gt; element.Name.ToString());
  
          foreach (KeyValuePair&lt;string, XElement&gt; 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);
      }
  
      /// &lt;summary&gt;
      ///A test for Get with one zombie.
      ///&lt;/summary&gt;
      [TestMethod()]
      public void SimpleGetTest()
      {
          IPersistentState target = CreateIPersistentState("../../../path/Data/SavedZombies.xml");
          string typeName = "zombie"; 
  
          IDictionary&lt;string, string&gt; expected = new Dictionary&lt;string, string&gt;();
          expected["health"] = "100";
          expected["positionX"] = "23";
          expected["positionY"] = "12";
          expected["speed"] = "2";
  
          IDictionary&lt;string, string&gt; actual = target.Get(typeName);
  
          foreach (KeyValuePair&lt;string, string&gt; entry in expected)
          {
              Assert.AreEqual(entry.Value, actual[entry.Key]);
          }
      }
  </code></pre>
  
  <p>The loading is still pretty crappy, and somehow I wasn't able to get the one-line <code>ToDictionary</code> to work with those two lambdas. I had to resort to that foreach loop. What am I doing wrong there?</p>