Unity精品专栏之序列化操作之XML(下)

Posted 小小Unity

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity精品专栏之序列化操作之XML(下)相关的知识,希望对你有一定的参考价值。

3.2.4 修改XML节点属性

在上一节我们掌握了生成创建XML文档,并增加其节点内容的方法,在这一小节我们将试着动态修改上一个文档中的XML内容:

/*
* / <summary>
* / 修改XML内容
* / </summary>
* / <param name="oldStr">要修改的内容</param>
* / <param name="type">内容的标签</param>
* / <param name="newStr">新内容</param>
*/

public void ChangeUserXML( string oldStr, string type, string newStr )
{
try
{
/* 加载XML文档 */
string fileName = Application.streamingAssetsPath + "/XMLTest.xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load( fileName );
/* 获取list节点下的所有节点 */
XmlNodeList xmlNodeList = xmlDocument.SelectSingleNode( "list" ).ChildNodes;


for ( int i = 0; i < xmlNodeList.Count; i++ )
{
/* 在子节点中找到我们需要修改的字符 */
if ( xmlNodeList[i].InnerText.Contains( oldStr ) )
{
/* 找到字符所在的类型并进行修改 */
xmlNodeList[i].SelectSingleNode( type ).InnerText = newStr;
/* 注意,修改完成后切记保存XML,否则修改无效 */
xmlDocument.Save( fileName );
}
}
}
catch ( System.Exception e )
{
Debug.Log( e.Message );
}
}

OK,根据以上方法,我们将之前的XML文档中的张三改为李四测测是否能达到我们想要的效果:

OK,测试发现我们的代码能达到我们预期的效果,以上的修改方法是针对内容修改的,接下来我们试试修改节点,比如以下XML:

<?xml version="1.0" encoding="UTF-8"?>

-<Root>
<View userPassword="123456" userID="himtnq24086@chacuo.net" id="01"/>
</Root>

我们试着修改以下上述的userPassword,代码如下:

/*
* / <summary>
* / 修改XML节点
* / </summary>
* / <param name="userName"></param>
* / <param name="newPassword"></param>
*/

public void ChangeUserInfo( string userName, string newPassword )
{
string fileName = Application.streamingAssetsPath + "/XMLTest.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load( fileName ); /* 加载文件;*/
XmlNodeList nodeList = xmlDoc.SelectSingleNode( "Root" ).ChildNodes; /* 取得Root结点下的所有子节点;*/
foreach ( XmlElement xe in nodeList )
{
if ( xe.GetAttribute( "userID" ) == userName ) /* 用XmlElement对象的GetAttribute方法取得结点;*/
{
xe.SetAttribute( "userPassword", newPassword );
xmlDoc.Save( fileName );
}
}
}

3.2.5 删除XML节点属性

在上一节中我们讲解了怎么修改XML的内容与节点,在这里我们在讲讲怎么删除XML节点,同样按照之前的XML文档为例,我们删除其中的张三以及其下的子节点

[ContextMenu( "删除XML节点" )]
public void DelectUserXML()
{
DelectUserXML( "张三", "name" );
}
/*
* / <summary>
* / 删除节点
* / </summary>
* / <param name="oldStr">要删除的节点值</param>
* / <param name="type">节点名称</param>
*/

private void DelectUserXML( string oldStr, string type )
{
string fileName = Application.streamingAssetsPath + "/XMLTest.xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load( fileName );
/* 获取list下的所有子节点 */
XmlNodeList xmlNodeList = xmlDocument.SelectSingleNode( "list" ).ChildNodes;
for ( int i = 0; i < xmlNodeList.Count; i++ )
{
/* 在子节点中找到我们需要删除的节点 */
if ( xmlNodeList[i].InnerText.Contains( oldStr ) )
{
/* 找到节点并将需要删除的次一节点删除 */
xmlNodeList[i].RemoveChild( xmlNodeList[i].SelectSingleNode( type ) );
/* 注意,修改完成后切记保存XML,否则修改无效 */
xmlDocument.Save( fileName );
}
}
}

来我们看看效果:

Unity精品专栏之序列化操作之XML(下)

接着我们在试试删除属性呢:

[ContextMenu( "删除XML属性" )]
public void DelectXMLAttributes()
{
DelectXMLAttributes( "02" );
}
/*
* / <summary>
* / 删除属性
* / </summary>
* / <param name="id">匹配值</param>
*/

private void DelectXMLAttributes( string id )
{
string fileName = Application.streamingAssetsPath + "/XMLTest.xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load( fileName );
XmlNode root = xmlDocument.SelectSingleNode( "list" );
if ( root == null )
{
Debug.LogError( "Save中止:XML文件未设置Root根节点。" );
return;
}
foreach ( XmlElement item in root.ChildNodes )
{
for ( int i = 0; i < item.Attributes.Count; i++ )
{
if ( item.Attributes[i].Value.Equals( id ) )
{
item.RemoveAll();
xmlDocument.Save( fileName );
}
}
}
}

OK,到这里我们学习了如何对XML进行删除处理。希望各位有收获

3.2.6 读取XML中的数据

在上面几节我们谈了对XML的“写”,现在我们来了解一下“读”,我们将上面我们使用代码生成的XML文档读出来,编译到Console窗口看看

public class XMLManager : MonoBehaviour
{
/*
* / <summary>
* / XML数据
* / </summary>
*/

public List<XMLData> data = new List<XMLData>();
/*
* / <summary>
* / 解析XML
* / </summary>
*/

[ContextMenu( "123" )]
public void RelaxXML()
{
string id = "", name = "", age = "", gender = "", salary = "";
string fileName = null;
XmlDocument xmlDocument = LoadOrCreateXML( out fileName );
if ( xmlDocument == null )
{
Debug.LogError( "未成功加载或创建用户自定义XML文件。" );

return;
}
XmlNodeList root = xmlDocument.SelectSingleNode( "list" ).ChildNodes;
if ( root == null )
{
Debug.LogError( "Save中止:XML文件未设置Root根节点。" );

return;
}

for ( int i = 0; i < root.Count; i++ )
{
id = root[i].Attributes[0].Value;
foreach ( XmlElement item in root[i].ChildNodes )
{
if ( item.Name.Equals( "name" ) )
{
name = item.InnerText;
}
if ( item.Name.Equals( "age" ) )
{
age = item.InnerText;
}
if ( item.Name.Equals( "gender" ) )
{
gender = item.InnerText;
}
if ( item.Name.Equals( "salary" ) )
{
salary = item.InnerText;
}
}
XMLData xML = new XMLData( id, name, age, gender, salary );
data.Add( xML );
}
}
}

/*
* / <summary>
* / XML数据Data
* / </summary>
*/

[Serializable]
public class XMLData
{
public string id, name, age, gender, salary;
public XMLData( string id, string name, string age, string gender, string salary )
{
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
this.salary = salary;
}
}

效果如下:

解析XML的节点总的来说还是挺简单的,只要大家能正确分析XML的结构即可根据API解析出来

到这里关于XML的操作在这里差不多介绍完了,在这里我们总结一下读写XML文档的一些关键API:

  • Attributes{get;} 属性,根据此API可获取属性的值,如

id = root[i].Attributes[0].Value;
  • InnerText{get;set;} 插入值,<name张三>/name>,可以取得上述格式中值,如:

name = item.InnerText;
  • SelectSingleNode(strng path) 根据路径获取单一Node节点,可用于获取根节点 如:

XmlNodeList root = xmlDocument.SelectSingleNode("Root").ChildNodes;

  • RemoveChild(XmlNode xmlnode) 移除子节点 ,如:

xmlNodeList[i].RemoveChild(xmlNodeList[i].SelectSingleNode(type));
  • RemoveAll 移除所有XmlElement,如

(XmlElement)item.RemoveAll();
  • CreateElement(string name) 创建节点,配合AppendChild(XmlNode xmlnode) (将xmlnode节点放置在XmlElement节点下) 如:

(XmlElement)root.AppendChild(account);
  • xmlElement.Load(string fileName) 按照路径加载XML,如:

string fileName = Application.streamingAssetsPath + "/XMLTest.xml";
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);


在这一章节我们也学到了一些关于XML的操作,相信各位也都了解掌握了。





以上是关于Unity精品专栏之序列化操作之XML(下)的主要内容,如果未能解决你的问题,请参考以下文章

零基础入门 Unity 之 UGUI 详解专栏 | 寻找C站宝藏

零基础入门 Unity 之 UGUI 详解专栏 | 寻找C站宝藏

[专栏日更]223 | Lua编程5之函数

Android源代码解析之--&gt;HandlerThread

Unity商业shader开发之高光RimColor,RimLight关键代码解析

[专栏日更]222 | Lua编程4之表达式和语句