2014-10-12 34 views
-1

我有這樣的XML(它修剪例如目的)接入和覆蓋XML節點(C#)

<?xml version="1.0" encoding="utf-8"?> 
<levels> 
    <level><!-- level 1 ! --> 
     <name>Level 1</name> 
     <title>Title 01</title> 
     <crystal01>false</crystal01> 
     <crystal02>false</crystal03> 
     <crystal02label>Label 1</crystal03label> 
     <crystal03>false</crystal04> 
    </level> 
    <level><!-- level 2 ! --> 
     <name>Level 2</name> 
     <title>Title 02</title> 
     <crystal01>true</crystal01> 
     <crystal02>true</crystal03> 
     <crystal02label>Label 2</crystal03label> 
     <crystal03>false</crystal04> 
    </level> 
</levels> 

我用這個腳本將數據加載到一些變量

public class LoadXmlData : MonoBehaviour // the Class 
{ 
    public int actualLevel = 1; 
    static int LevelMaxNumber; 
    static int WaipointCounter = 0; 

    public static string lvlname = ""; 
    public static string lvltitle = ""; 

    public static string crystal01 = ""; 
    public static string crystal02 = ""; 
    public static string crystal02label = ""; 
    public static string crystal03 = ""; 

    public TextAsset XMLData; 

    List<Dictionary<string,string>> levels = new List<Dictionary<string,string>>(); 
    Dictionary<string,string> obj; 


    void Start() 
    { GetLevel(); 
     StartCoroutine(LevelLoadInfo(0.0F)); 
     LevelMaxNumber = levels.Count; 
    } 

    public void GetLevel() 
    { 
     XmlDocument xmlDoc = new XmlDocument(); // xmlDoc is the new xml document. 
     xmlDoc.LoadXml(XMLData.text); // load the file. 
     XmlNodeList levelsList = xmlDoc.GetElementsByTagName("level"); // array of the level nodes. 

     foreach (XmlNode levelInfo in levelsList) 
     { 
      XmlNodeList levelcontent = levelInfo.ChildNodes; 
      obj = new Dictionary<string,string>(); 

      foreach (XmlNode levelsItens in levelcontent) // levels itens nodes. 
      { 
       if(levelsItens.Name == "name") 
       { 
        obj.Add("name",levelsItens.InnerText); // put this in the dictionary. 
       } 


       if(levelsItens.Name == "title") 
       { 
        obj.Add("title",levelsItens.InnerText); // put this in the dictionary. 
       } 


       if(levelsItens.Name == "crystal01") 
       { 
        obj.Add("crystal01",levelsItens.InnerText); // put this in the dictionary. 

       } 

       if(levelsItens.Name == "crystal02") 
       { 
        obj.Add("crystal02",levelsItens.InnerText); // put this in the dictionary. 

       } 

       if(levelsItens.Name == "crystal02label") 
       { 
        obj.Add("crystal02label",levelsItens.InnerText); // put this in the dictionary. 

       } 


       if(levelsItens.Name == "crystal03") 
       { 
        obj.Add("crystal03",levelsItens.InnerText); // put this in the dictionary. 

       } 

      } 
      levels.Add(obj); // add whole obj dictionary in the levels[]. 
     } 
    } 


    IEnumerator LevelLoadInfo(float Wait) 
    { 
     levels[actualLevel-1].TryGetValue("name",out lvlname); 

     levels[actualLevel-1].TryGetValue("title",out lvltitle); 

     levels[actualLevel-1].TryGetValue("crystal01",out crystal01); 

     levels[actualLevel-1].TryGetValue("crystal02",out crystal02); 

     levels[actualLevel-1].TryGetValue("crystal02label",out crystal02label); 

     levels[actualLevel-1].TryGetValue("crystal03",out crystal03); 

     yield return new WaitForSeconds(Wait); 

    } 

    void Update() 
    { 
    } 

} 

一切工作正常,但即時通訊真的掙扎了幾天,使一個功能訪問某個節點,ovewrite它的數據和保存xml,我知道這是一件簡單的事情,但我沒有得到它(我是一個3D藝術家,即時編程自去年以來,所以還處於學習階段),例如,我如何編輯文件中的「crystal02」值vel 2並保存xml? 在此先感謝!

+0

我強烈建議使用Linq來代替XML。 – Alireza 2014-10-12 14:19:53

回答

0

你必須修正你的XML一點,所以它會解析。打開節點名稱需要匹配關閉節點名稱,所以從這個:

<crystal02>false</crystal03> 

這樣:

<crystal02>false</crystal02> 

要回答你的問題有關更新的單個元素,由於您使用XmlDocument的閱讀您的字符串,這裏是你如何去尋找XPath的單個元素,更新它在XmlDocument中的值,然後將XmlDocument序列化回字符串。您的更新方法可能如下所示:

var doc = new System.Xml.XmlDocument(); 
// strXml is the string containing your XML from XMLData.Text 
doc.LoadXml(strXml); 
// Find the node by an XPath expression 
var l2cr3 = (XmlElement) doc.SelectSingleNode("levels/level[name='Level 2']/crystal03"); 
// Update it 
l2cr3.InnerText = "true"; 
// Update the string in memory 
var sbOut = new System.Text.StringBuilder(); 
using (var writer = XmlWriter.Create(sbOut)) { 
    doc.Save (writer); 
} 
strXml = sbOut.ToString(); 

這將更新內存中的XML字符串。它不會堅持到一個文件。如果你想堅持一個文件,你可能需要使用doc.Load(「path/to/file.xml」)和doc.Save(「path/to/file.xml」);

我注意到你的字符串實際上是來自TextAsset(假設爲Unity),如果是這種情況,我不確定你想如何將更新的XML字符串保存到文件中,或者即使你想要做那。如果你這樣做,這是一個不同的問題,但​​這樣說:

它不適用於文本文件生成在運行時。爲此,您需要使用傳統的輸入/輸出編程技術 來讀取和寫入外部文件 。

+0

謝謝! xml錯字是在複製粘貼xml的時候創建的,「SelectSingleNode」是我正在搜索的內容,目前正在測試,但它已經工作,再次感謝DaveC – Mauricio 2014-10-13 17:27:45