2010-03-13 77 views
7

我很難做這個看似簡單的任務。我想加載XML文件與加載藝術資產一樣容易:XNA:加載和讀取XML文件的最佳方法?

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

我不知道如何做到這一點。這tutorial似乎有幫助,但我怎麼得到一個StorageDevice實例?

我有現在一些工作,但感覺很哈克:

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; 
     } 

我將此下面的XML文件:

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

而且它能夠通過這個單元測試:

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]); 
     } 
    } 

目前方法的缺點:文件加載效果不佳,並且鍵與值匹配就像它比必要的更努力。另外,我懷疑這種方法會在XML中出現多個條目而崩潰。

我無法想象這是最佳實施。

UPDATE:繼@Peter Lillevold的建議,我已經改變了這一點:

​​

加載仍然是相當糟糕的,並不知我是不是能夠得到單行ToDictionary與這兩個lambda一起工作。我不得不求助於那個foreach循環。我在那裏做錯了什麼?

+0

你有一個錯字。我的示例中的@只能與字符串文字一起使用,而不能與字符串變量或參數一起使用。 – 2010-03-14 02:58:24

+1

你知道XNA內容管道ALREADY支持XML文件,不是嗎?因此,可以從字面上使用與加載藝術文件來加載XML文件相同的語法。 – 2011-07-05 05:16:27

回答

8

還有新的和有光澤的​​(其中運動Linq to XML)。此示例將加載一個XML文件,查找殭屍和轉儲值到字典:

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

如果你寧願挑明確每個值(並使用鑄造自動轉換成適當的值類型),你可以這樣做:

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"); 

更新:固定一些錯別字和清理了一下,你的Get方法應該是這樣的:

public IDictionary<string, string> Get(string typeName) 
{ 
    var zombie = root.Element(typeName); 
    return zombie.Elements() 
      .ToDictionary(
        element => element.Name.ToString(), 
        element => element.Value); 
} 
+0

而且,「殭屍」前的@符號有什麼意義? – 2010-03-14 02:23:58

+0

另外,我怎樣才能比uri更優雅地加載文件? (就像內容管道一樣?) – 2010-03-14 02:28:40

+0

對不起,這裏@沒有必要。當字符串應該是逐字的時候,它用在字符串前面。 你可以看看爲你的文件類型製作一個自定義的流水線處理器。看看這個:http://msdn.microsoft.com/en-us/library/bb447754.aspx – 2010-03-14 02:54:06

2
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... 
} 

或者這在XNA中不起作用?

+0

我會試試。但是,首先從文件中獲取xmlString的更好方法是什麼? – 2010-03-13 21:06:01

+0

更新了代碼,因爲我犯了一個錯誤。 (doc.Load => doc.LoadXml) – TJMonk15 2010-03-14 01:25:24

+0

似乎XmlDocument不包含在.NET的XNA發行版中,或者至少在我嘗試使用它時抱怨。 – Arkiliknam 2012-12-16 15:32:34