Unity3D XML文件解析和增删改

一般很多都是xml解析的,因为实际开发中很少用文本的,所以上篇说的txt文档解析几乎可以忽略,现在大部分都是xml和json,比如装备表等,都是策划写好的,所以现在先看下xml的解析。

一、xml的解析

首先新建一个xml,可以命名为item.xml,拖进assets里面,内容如下

<item>
  <item1>
    <id>1</id>
    <name>china</name>
    <year>2016</year>
  </item1>
  <item2>
    <id>2</id>
    <name>usa</name>
    <year>2017</year>
  </item2>
</item>

通过这个xml来解析。然后写一个.cs文件,注意需要导入这两个头文件

using System.Xml;     //xml操作
using System.IO;     //file操作

解析函数如下

//解析xml
	void parseXml(){
		//也可以前面加上@,区别就是有@的话,双引号里面的内容不转义,比如" \" "
		//string filePath = [email protected]"/Resources/item.xml";
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);

				if(ele.Name == "item1"){
				//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
							id1 = i1.InnerText;
						}
						if(i1.Name == "name"){
							name1 = i1.InnerText;
						}
						if(i1.Name=="year"){
							year1 = i1.InnerText;
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
							id2 = i2.InnerText;
						}
						if(i2.Name == "name"){
							name2 = i2.InnerText;
						}
						if(i2.Name=="year"){
							year2 = i2.InnerText;
						}
					}
				}

			}
		}
		Debug.Log("id1:  "+id1);
		Debug.Log("name1:  "+name1);
		Debug.Log("year1:  "+year1);
		Debug.Log("id2:  "+id2);
		Debug.Log("name2:  "+name2);
		Debug.Log("year2:  "+year2);
	}

通过解析即可得到xml的值

屏幕快照 2016-06-22 13.54.08.png


后面的增删改其实不怎么用,因为一般都是策划直接修改表,而不用代码修改,但是还是可以看看。

二、创建xml表

代码如下,当然前面说的那两个头文件也是要导入的:

void createXml(){
		string filePath = Application.dataPath+"/Resources/new.xml";
		if(!File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			//先创建出所有节点和他们的值
			//根节点
			XmlElement root = xmlDoc.CreateElement("root");
			//第一个节点和赋值
			XmlElement xmlItem1 = xmlDoc.CreateElement("item1");
			XmlElement xmlId = xmlDoc.CreateElement("id");
			XmlElement xmlPrice = xmlDoc.CreateElement("price");
			xmlItem1.SetAttribute("name","hu");//属性值根据需求可有可无
			xmlId.InnerText ="1";
			xmlPrice.InnerText = "200";
			//第二个节点和赋值
			XmlElement xmlItem2 = xmlDoc.CreateElement("item2");
			XmlElement xmlId2 = xmlDoc.CreateElement("id");
			XmlElement xmlPrice2 = xmlDoc.CreateElement("price");
			xmlId2.InnerText ="2";
			xmlPrice.InnerText = "300";
			//调整结构
			xmlItem1.AppendChild(xmlId);
			xmlItem1.AppendChild(xmlPrice);
			xmlItem2.AppendChild(xmlId2);
			xmlItem2.AppendChild(xmlPrice2);
			root.AppendChild(xmlItem1);
			root.AppendChild(xmlItem2);
			xmlDoc.AppendChild(root);
			//保存
			xmlDoc.Save(filePath);
		}
	}

思路就是先创建各个节点的值,最后通过AppendChild()这个函数调整节点的父子关系。

得到的xml文件内容

屏幕快照 2016-06-22 14.28.39.png

因为有的时候u3d刷新不及时,可能创建好之后需要去文件夹下面去看

屏幕快照 2016-06-22 14.28.49.png屏幕快照 2016-06-22 14.26.35.png

三、修改XML

修改xml的方法和解析xml的方法是一样的,只是解析的时候是把值赋值出来用,而修改xml的方法是给里面的节点赋值,然后保存xml。所以整个代码除了赋值和解析不一样,其他都是一样的。

代码如下:

	void updateXml(){
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);
				
				if(ele.Name == "item1"){
					//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
//							id1 = i1.InnerText;
							i1.InnerText="update_id";
						}
						if(i1.Name == "name"){
//							name1 = i1.InnerText;
							i1.InnerText = "update_name";
						}
						if(i1.Name=="year"){
//							year1 = i1.InnerText;
							i1.InnerText = "update_yar";
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
//							id2 = i2.InnerText;
							i2.InnerText = "update_id2";
						}
						if(i2.Name == "name"){
//							name2 = i2.InnerText;
							i2.InnerText="update_name2";
						}
						if(i2.Name=="year"){
//							year2 = i2.InnerText;
							i2.InnerText ="update_year2";
						}
					}
				}
				
			}
			//比读取多了一步保存
			xmlDoc.Save(filePath);
		}
	}

得到的效果

屏幕快照 2016-06-22 14.35.22.png

四、删除xml节点内容

删除节点内容和修改xml节点内容是一样的,只是这次不修改数值,而是直接调用RemoveAll()的方法删除节点值

代码如下:

void deleXml(){
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);
				
				if(ele.Name == "item1"){
					//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
							//							id1 = i1.InnerText;
							i1.RemoveAll();
						}
						if(i1.Name == "name"){
							//							name1 = i1.InnerText;
							i1.RemoveAll();
						}
						if(i1.Name=="year"){
							//							year1 = i1.InnerText;
							i1.RemoveAll();
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
							//							id2 = i2.InnerText;
							i2.InnerText = "update_id2";
						}
						if(i2.Name == "name"){
							//							name2 = i2.InnerText;
							i2.InnerText="update_name2";
						}
						if(i2.Name=="year"){
							//							year2 = i2.InnerText;
							i2.InnerText ="update_year2";
						}
					}
				}
				
			}
			//比读取多了一步保存
			xmlDoc.Save(filePath);
		}
	}

得到的效果

屏幕快照 2016-06-22 15.00.00.png

五、整个工程完整的代码:

这个就是整个工程完整的代码,可以参考下:

using UnityEngine;
using System.Collections;
using System.Xml;     //xml操作
using System.IO;     //file操作
public class XMLtest : MonoBehaviour {
	//
	private string id1;
	private string name1;
	private string year1;
	private string id2;
	private string name2;
	private string year2;
	// Use this for initialization
	void Start () {

	}
	// Update is called once per frame
	void Update () {
		//按下A键解析文件内容
		//按下B键创建文件内容
		//按下C键更新文件内容
		//按下D键删除文件内容
		if(Input.GetKeyDown(KeyCode.A)){
			parseXml();
		}
		if(Input.GetKeyDown(KeyCode.B)){
			createXml();
		}
		if(Input.GetKeyDown(KeyCode.C)){
			updateXml();
		}
		if(Input.GetKey(KeyCode.D)){
			deleXml();
		}
	}

	//解析xml
	void parseXml(){
		//也可以前面加上@,区别就是有@的话,双引号里面的内容不转义,比如" \" "
		//string filePath = [email protected]"/Resources/item.xml";
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);

				if(ele.Name == "item1"){
				//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
							id1 = i1.InnerText;
						}
						if(i1.Name == "name"){
							name1 = i1.InnerText;
						}
						if(i1.Name=="year"){
							year1 = i1.InnerText;
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
							id2 = i2.InnerText;
						}
						if(i2.Name == "name"){
							name2 = i2.InnerText;
						}
						if(i2.Name=="year"){
							year2 = i2.InnerText;
						}
					}
				}

			}
		}
		Debug.Log("id1:  "+id1);
		Debug.Log("name1:  "+name1);
		Debug.Log("year1:  "+year1);
		Debug.Log("id2:  "+id2);
		Debug.Log("name2:  "+name2);
		Debug.Log("year2:  "+year2);
	}

	void createXml(){
		string filePath = Application.dataPath+"/Resources/new.xml";
		if(!File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			//先创建出所有节点和他们的值
			//根节点
			XmlElement root = xmlDoc.CreateElement("root");
			//第一个节点和赋值
			XmlElement xmlItem1 = xmlDoc.CreateElement("item1");
			XmlElement xmlId = xmlDoc.CreateElement("id");
			XmlElement xmlPrice = xmlDoc.CreateElement("price");
			xmlItem1.SetAttribute("name","hu");//属性值根据需求可有可无
			xmlId.InnerText ="1";
			xmlPrice.InnerText = "200";
			//第二个节点和赋值
			XmlElement xmlItem2 = xmlDoc.CreateElement("item2");
			XmlElement xmlId2 = xmlDoc.CreateElement("id");
			XmlElement xmlPrice2 = xmlDoc.CreateElement("price");
			xmlId2.InnerText ="2";
			xmlPrice.InnerText = "300";
			//调整结构
			xmlItem1.AppendChild(xmlId);
			xmlItem1.AppendChild(xmlPrice);
			xmlItem2.AppendChild(xmlId2);
			xmlItem2.AppendChild(xmlPrice2);
			root.AppendChild(xmlItem1);
			root.AppendChild(xmlItem2);
			xmlDoc.AppendChild(root);
			//保存
			xmlDoc.Save(filePath);
		}
	}

	void updateXml(){
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);
				
				if(ele.Name == "item1"){
					//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
//							id1 = i1.InnerText;
							i1.InnerText="update_id";
						}
						if(i1.Name == "name"){
//							name1 = i1.InnerText;
							i1.InnerText = "update_name";
						}
						if(i1.Name=="year"){
//							year1 = i1.InnerText;
							i1.InnerText = "update_yar";
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
//							id2 = i2.InnerText;
							i2.InnerText = "update_id2";
						}
						if(i2.Name == "name"){
//							name2 = i2.InnerText;
							i2.InnerText="update_name2";
						}
						if(i2.Name=="year"){
//							year2 = i2.InnerText;
							i2.InnerText ="update_year2";
						}
					}
				}
				
			}
			//比读取多了一步保存
			xmlDoc.Save(filePath);
		}
	}

	void deleXml(){
		string filePath = Application.dataPath+"/Resources/item.xml";
		if(File.Exists(filePath)){
			XmlDocument xmlDoc = new XmlDocument();
			xmlDoc.Load(filePath);
			XmlNodeList node = xmlDoc.SelectSingleNode("item").ChildNodes;
			//遍历节点
			foreach(XmlElement ele in node){
				//item下面的节点
				Debug.Log(ele.Name);
				
				if(ele.Name == "item1"){
					//first item1
					foreach(XmlElement i1 in ele.ChildNodes){
						Debug.Log(i1.Name);
						if(i1.Name == "id"){
							//							id1 = i1.InnerText;
							i1.RemoveAll();
						}
						if(i1.Name == "name"){
							//							name1 = i1.InnerText;
							i1.RemoveAll();
						}
						if(i1.Name=="year"){
							//							year1 = i1.InnerText;
							i1.RemoveAll();
						}
					}
				}
				if(ele.Name == "item2"){
					//first item1
					foreach(XmlElement i2 in ele.ChildNodes){
						Debug.Log(i2.Name);
						if(i2.Name == "id"){
							//							id2 = i2.InnerText;
							i2.InnerText = "update_id2";
						}
						if(i2.Name == "name"){
							//							name2 = i2.InnerText;
							i2.InnerText="update_name2";
						}
						if(i2.Name=="year"){
							//							year2 = i2.InnerText;
							i2.InnerText ="update_year2";
						}
					}
				}
				
			}
			//比读取多了一步保存
			xmlDoc.Save(filePath);
		}
	}
}

六、参考文章:

Last modification:January 1st, 1970 at 08:00 am
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment