2014-10-12 33 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