推荐阅读
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新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()函数进行添加。
七、后言
代码没有什么难度,来来回回就那么几行代码。
需要注意的就是节点不要找错了。