【Unity3D读取数据】(三)Xml文件操作(创建、读取、写入、修改)

153 阅读5分钟

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

推荐阅读

大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。

一、前言

在程序开发中,经常会遇到要从外部文件中读取数据的情况,文件类型也比较多。

于是,小魔龙就将常见的文件类型:Txt、Json、Xml、Excel、Csv,读取、修改、保存等常见操作代码总结下来。

一方面可以自己复习,另一方面也希望可以帮助更多的人吧。

这是本系列文章第三篇: 【Unity3D读取数据】(一)Txt文档操作(创建、读取、写入、修改) 【Unity3D读取数据】(二)Json文件操作(创建、读取、解析、修改) 【Unity3D读取数据】(三)Xml文件操作(创建、读取、写入、修改) 【Unity3D读取数据】(四)Excel文件操作(创建、读取、写入、修改) 【Unity3D读取数据】(五)Csv文件操作(创建、读取、写入、修改)

二、唠叨两句

Xml文件,是一个可拓展标记语言,它可以用来标记数据局、定义数据类型等。

需要注意的是它的节点,Xml文件必须要有一个根节点,然后根据根节点去找子节点,然后根据子节点去找子节点的子节点,所以在这一点上跟其他文件还是不太一样的。

而正是由于这个特点,Xml非常适合在万维网传输,提供统一的方法来描述的结构化数据。

下面就来了解一下如何创建Xml文件吧。

三、创建Xml文件

创建Xml需要注意层级,一层有一层的添加到xml中:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        CreateXML();
    }

    //创建XML
    void CreateXML()
    {
        string path = Application.streamingAssetsPath + "/data.xml";
        //创建xml文档
        XmlDocument xml = new XmlDocument();
        //创建根节点
        XmlElement root = xml.CreateElement("Node");

        //创建根节点的子节点
        XmlElement element = xml.CreateElement("Person");
        //设置根节点的子节点的属性
        element.SetAttribute("id", "1");
        //添加两个子节点到根节点的子节点的下面
        XmlElement elementChild1 = xml.CreateElement("Name");
        elementChild1.SetAttribute("name", "");
        elementChild1.InnerText = "王五";
        XmlElement elementChild2 = xml.CreateElement("Age");
        elementChild2.SetAttribute("age", "");
        elementChild2.InnerText = "18";
        //把节点一层一层的添加至xml中,注意他们之间的先后顺序,这是生成XML文件的顺序
        element.AppendChild(elementChild1);
        element.AppendChild(elementChild2);


        //再创建一个根节点的子节点
        XmlElement element2 = xml.CreateElement("Person");
        //设置根节点的子节点的属性 名字一样 属性不一样也可以
        element2.SetAttribute("id", "2");
        //添加两个子节点到根节点的子节点的下面
        XmlElement elementChild3 = xml.CreateElement("Name");
        elementChild3.SetAttribute("name", "");
        elementChild3.InnerText = "李四";
        XmlElement elementChild4 = xml.CreateElement("Age");
        elementChild4.SetAttribute("age", "");
        elementChild4.InnerText = "22";
        element2.AppendChild(elementChild3);
        element2.AppendChild(elementChild4);

        //把节点一层一层的添加至xml中,注意他们之间的先后顺序,这是生成XML文件的顺序
        root.AppendChild(element);
        root.AppendChild(element2);
        xml.AppendChild(root);

        //最后保存文件
        xml.Save(path);
    }
}

运行结果: 在这里插入图片描述 可以根据结果,再去研究代码。

四、读取Xml文件

读取Xml,需要从根节点一层一层往下找,根节点找子节点,子节点找孙节点。

属性查找

我们就先以查找属性的方式找到我们需要的节点数据:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        LoadXml();
    }

    //读取XML
    void LoadXml()
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(Application.streamingAssetsPath + "/data.xml");
        XmlNodeList xmlNodeList = xml.SelectSingleNode("Node").ChildNodes;
        //遍历所有子节点
        foreach (XmlElement xl1 in xmlNodeList)
        {
            if (xl1.GetAttribute("id") == "1")
            {
                //继续遍历id为1的节点下的子节点
                foreach (XmlElement xl2 in xl1.ChildNodes)
                {
                    if (xl2.GetAttribute("name") == "")
                    {
                        Debug.Log(xl2.InnerText);
                    }
                    else if (xl2.GetAttribute("age") == "")
                    {
                        Debug.Log(xl2.InnerText);
                    }
                }
            }
        }
    }
}

运行结果: 在这里插入图片描述

节点名字查找

根据节点的名字进行查找:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        ReadXml();
    }

    //读取XML
    void ReadXml()
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(Application.streamingAssetsPath + "/data.xml");
        XmlNodeList xmlNodeList = xml.SelectSingleNode("Node").ChildNodes;
        //遍历所有子节点
        foreach (XmlElement xl1 in xmlNodeList)
        {
            if (xl1.Name == "Person" && xl1.GetAttribute("id") == "1")
            {
                //继续遍历名字叫做Person,id为1的节点下的子节点
                foreach (XmlElement xl2 in xl1.ChildNodes)
                {
                    if (xl2.Name == "Name")
                    {
                        Debug.Log(xl2.InnerText);
                    }
                    else if (xl2.Name == "Age")
                    {
                        Debug.Log(xl2.InnerText);
                    }
                }
            }
        }
    }
}

不按照名字跟属性进行查找

每次查找还需要知道属性的名字或者节点的名字,多麻烦呀。 那么有没有不需要知道名字跟节点名字就可以查找的:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        ReadXml();
    }

    //读取XML
    void ReadXml()
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(Application.streamingAssetsPath + "/data.xml");
        //获取根节点
        XmlNode rootNode = xml.FirstChild;
        XmlNodeList nodeList = rootNode.ChildNodes;
        //遍历所有子节点
        int Count = nodeList.Count;
        for (int i = 0; i < Count; i++)
        {
            Debug.Log(nodeList.Item(i).InnerText);
        }
    }
}

五、修改Xml文件

修改Xml文件的数据,就需要根据节点的名字或者节点的属性找到对应的节点修改数据,之后保存文件即可:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        UpdateXML();
    }

    //修改XML
    void UpdateXML()
    {
        string path = Application.streamingAssetsPath + "/data.xml";
        if (File.Exists(path))
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(path);
            XmlNodeList xmlNodeList = xml.SelectSingleNode("Node").ChildNodes;
            foreach (XmlElement xl1 in xmlNodeList)
            {
                if (xl1.GetAttribute("id") == "1")
                {
                    //把id为1的属性改为5
                    xl1.SetAttribute("id", "5");
                }
                if (xl1.GetAttribute("id") == "2")
                {
                    foreach (XmlElement xl2 in xl1.ChildNodes)
                    {
                        if (xl2.Name == "Name")
                        {
                            //修改其里面的内容
                            xl2.SetAttribute("name", "abc");
                            xl2.InnerText = "赵六";
                        }
                    }
                }
            }
            xml.Save(path);
        }
    }
}

六、添加数据

接下来,就来看一下如何在Xml文件后面追加数据:

using System.IO;
using System.Xml;
using UnityEngine;

public class Demo5 : MonoBehaviour
{
    void Start()
    {
        AddXMLData();
    }

    //添加XML
    void AddXMLData()
    {
        string path = Application.streamingAssetsPath + "/data.xml";
        if (File.Exists(path))
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(path);
            XmlNode root = xml.SelectSingleNode("Node");
            XmlElement element = xml.CreateElement("Person");
            //设置节点的属性
            element.SetAttribute("id", "2");
            XmlElement elementChild1 = xml.CreateElement("Name");
            elementChild1.SetAttribute("name", "ced");
            elementChild1.InnerText = "李四";
            XmlElement elementChild2 = xml.CreateElement("Age");
            elementChild2.SetAttribute("age", "123");
            elementChild2.InnerText = "11";
            //把节点一层一层的添加至xml中,注意他们之间的先后顺序,这是生成XML文件的顺序
            element.AppendChild(elementChild1);
            element.AppendChild(elementChild2);
            root.AppendChild(element);
            xml.AppendChild(root);
            //最后保存文件
            xml.Save(path);
        }
    }
}

添加数据使用AppendChild()函数进行添加。

七、后言

代码没有什么难度,来来回回就那么几行代码。

需要注意的就是节点不要找错了。