【问题标题】:Access and overwrite an xml node (C#)访问和覆盖 xml 节点 (C#)
【发布时间】:2014-10-12 13:49:42
【问题描述】:

我有这个 xml(为了举例,它被修剪了)

<?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()
    {
    }

}

一切正常,但我真的努力了几天来创建一个访问某个节点的函数,覆盖它的数据并保存 xml,我知道这有点简单,但我不明白(我是 3d艺术家,我从去年开始编程,所以,还在学习阶段),例如,我如何在级别 2 中编辑“水晶02”值并保存 xml? 提前致谢!

【问题讨论】:

  • 我强烈推荐使用 Linq to XML。

标签: c# xml xmldocument


【解决方案1】:

您必须稍微修正一下您的 XML,以便它能够解析。打开节点名称需要匹配关闭节点名称,所以从这里:

<crystal02>false</crystal03>

到这里:

<crystal02>false</crystal02>

要回答有关更新单个元素的问题,因为您使用 XmlDocument 来读取字符串,以下是您可以如何通过 XPath 查找单个元素,更新其在 XmlDocument 中的值,然后序列化 XmlDocument回到一个字符串。您的 Update 方法可能如下所示:

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 字符串保存回文件,或者即使您想这样做.如果你这样做,那就是另一个问题了,但Unity manual 是这样说的:

它不适用于在运行时生成文本文件。为此你 将需要使用传统的输入/输出编程技术 读写外部文件。

【讨论】:

  • 谢谢!在此处复制粘贴 xml 时出现了 xml 拼写错误,“SelectSingleNode”是我正在搜索的内容,目前正在测试,但它已经在工作,再次感谢 DaveC
猜你喜欢
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
相关资源
最近更新 更多