Unity学习笔记--数据持久化XML文件(1)
XML相关
Xml是可拓展标记语言,一种文件格式。我们使用xml来完成对数据持久化的存储。等待我们有一程序运行结束之后,将内存中的数据进行保存,(保存在硬盘/服务器)实现对数据的持久化存储。
xml文件的读取和保存以及修改
要点:
XMl文件的加载
XML文件节点的查找访问
XML文件节点内容的读取 (InnerText还是Attributes["id"].Value 形式访问)
代码中有详细注释!可供参考对比学习!
using System.IO;
using System.Xml;
using UnityEngine;
namespace Building.XML
{
public class LoadXMLFile:MonoBehaviour
{
private void Start()
{
//得到xml文件
XmlDocument xmlFile = new XmlDocument();
//通过加载text格式进行解析成xml形式进行获取
//TextAsset textAsset = Resources.Load<TextAsset>("Text");
// xmlFile.LoadXml(textAsset.text);
//通过路径进行加载
xmlFile.Load(Application.streamingAssetsPath+"/Text.xml");
//读取xml中节点
XmlNode root = xmlFile.SelectSingleNode("PlayerInfo");
XmlNode nodeName = root.SelectSingleNode("Name");
XmlNode nodeList = root.SelectSingleNode("Item");
//获取自定义版本的数据结构类型
print(nodeList.Attributes["id"].Value);
print(nodeList.Attributes["size"].Value);
//或者
print(nodeList.Attributes.GetNamedItem("id").Value);
print(nodeList.Attributes.GetNamedItem("size").Value);
//直接获取数组中的元素
XmlNode tempNodeList1 = root.SelectSingleNode("ItemList1");
XmlNodeList xmlNodeList1 = tempNodeList1.SelectNodes("Item");
//找出List中所有的节点 打印节点组中的 id size节点的InnerText
//var 类型推断不出来 XmlNode类型
foreach (XmlNode item in xmlNodeList1)
{
print(item.Name);
print(item.SelectSingleNode("id").InnerText);
/* <Item>
<id>2003</id>> 通过InnerText来访问<> <>中间的内容
<size>17.5</size>>
</Item>>*/
print(item.SelectSingleNode("size").InnerText);
}
for (int i = 0; i < xmlNodeList1.Count; i++)
{
print(xmlNodeList1[i].Name);
print(xmlNodeList1[i].SelectSingleNode("id").InnerText);
print(xmlNodeList1[i].SelectSingleNode("size").InnerText);
}
//直接获取数组中的元素 形式 innerText访问还是获取 Attributes["size"].Value 访问数值
//-------注意区分元素中是否还有子节点 根据是否有子节点来选择获取节点内容
XmlNode tempNodeList = root.SelectSingleNode("ItemList");
XmlNodeList xmlNodeList = tempNodeList.SelectNodes("Item");
//找出List中所有的节点 打印节点组中的 id size节点的InnerText
//var 类型推断不出来 XmlNode类型
foreach (XmlNode item in xmlNodeList)
{
print(item.Name);
print(item.Attributes["id"].InnerText);
print(item.Attributes["size"].Value);
}
for (int i = 0; i < xmlNodeList.Count; i++)
{
print(xmlNodeList[i].Name);
print(xmlNodeList[i].Attributes["id"].Value); //<Item id="2011" size="15.5"/>
//单行内嵌的 通过Attributs["name"].Value访问
print(xmlNodeList[i].Attributes["size"].Value);
}
//============================读================
//==================xml存储的路径
// 1.Resources 可读 不可写 打包后找不到 ×
// 2.Application.streamingAssetsPath 可读 PC端可写 找得到 ×
// 3.Application.dataPath 打包后找不到 ×
// 4.Application.persistentDataPath 可读可写找得到 √
string path = Application.streamingAssetsPath + "/xmlSaveFile.xml";
print(Application.persistentDataPath);
//创建固定版本信息
XmlDocument saveXmlFile = new XmlDocument();
//文件格式声明
XmlDeclaration xmlDeclaration = saveXmlFile.CreateXmlDeclaration("1.0", "utf-8", "");
saveXmlFile.AppendChild(xmlDeclaration);
//添加根节点
//这里以存储班级信息为例子
XmlElement classInfo =saveXmlFile.CreateElement("ClassInfo");
saveXmlFile.AppendChild(classInfo);
//创建子节点
XmlElement teacher = saveXmlFile.CreateElement("teacher");
classInfo.AppendChild(teacher);
XmlElement teacherName = saveXmlFile.CreateElement("teacherName");
teacherName.InnerText = "TonyChang";
teacher.AppendChild(teacherName);
XmlElement teacherId = saveXmlFile.CreateElement("teacherId");
teacherId.InnerText = "3306";//设置teacherID名称
teacher.AppendChild(teacherId);
//学生信息模块
XmlElement stusElement = saveXmlFile.CreateElement("Students");
XmlElement stuEle;//学生信息
for (int i = 0; i < 15; i++)
{
stuEle = saveXmlFile.CreateElement("Student");
stuEle.SetAttribute("stuNo", (i + 1).ToString());
stuEle.SetAttribute("age", 19.ToString());
stusElement.AppendChild(stuEle);
}
//学生信息模块添加到xml文件中
classInfo.AppendChild(stusElement);
//保存Xml文件
saveXmlFile.Save(path);
//----------------------XML的内容修改------------------------
if (File.Exists(path))
{
XmlDocument Xml1 = new XmlDocument();
//加载到新建的的xml文件中
Xml1.Load(path);
//获取要修改的文件节点
XmlNode changeNode;
changeNode = Xml1.SelectSingleNode("ClassInfo/teacher/teacherId");
//将3306-->8888
changeNode.InnerText = "8888";
//---删除(通过父节点删除)
XmlNode FatherNode = Xml1.SelectSingleNode("ClassInfo/teacher");
FatherNode.RemoveChild(changeNode);
//---添加新的节点
XmlNode changedNode=Xml1.CreateElement("teacherId");
changedNode.InnerText = "8888";
FatherNode.AppendChild(changedNode);
//修改了记得保存
Xml1.Save(path);
}
}
}
}
textXML文件
<?xml version="1.0" encoding="utf-8"?>
<!--注释内容-->
<PlayerInfo >
<name>TonyChang</name>
<age>18</age>
<height>175.5</height>>
<Item id="1997" size="12.5"/>
<Item1>
<id>1998</id>>
<size>12.25</size>
</Item1>>
<ItemList1>
<!--属性
和元素节点的区别?
表现形式不同的同种意义
-->
<Item>
<id>2002</id>>
<size>16.5</size>>
</Item>>
<Item>
<id>2003</id>>
<size>17.5</size>>
</Item>>
<Item>
<id>2004</id>>
<size>18.5</size>>
</Item>>
</ItemList1>
<ItemList>
<!--属性
和元素节点的区别?
表现形式不同的同种意义
-->
<Item id="2011" size="15.5"/>
<Item id="2012" size="16.5"/>
<Item id="2013" size="17.5"/>
</ItemList>
</PlayerInfo>

文件格式如图所示;
生成新建的“xmlSaveFile.xml”文件内容

XML的序列化与反序列化
序列化:
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;
public class Test
{
public int testPub = 10;
private int testPri = 5;
protected int testProtect = 12;
internal int testInter = 15;
public string testStr = "TonyChang";
//属性
public int testPro { get; set; }
//数组
public int[] arrayInt=new []{2,4,6,8};
//自定义类
public Test2 Test2 = new Test2();
//list
//更改数组属性名字
[XmlArray("IntList")]
[XmlArrayItem("TCInt")]
public List<int> listInt=new List<int>(){1,5,7,8,9};
//不支持字典
// public Dictionary<int, string> testDic = new Dictionary<int, string>() {{1, "Jerry"},{2,"Tom"}};
}
public class Test2
{
//属性标签
[XmlAttribute("Test2")] public int xmlTest = 5;
[XmlAttribute()] public float test2Float = 6.6f;
[XmlAttribute()] public bool aryUok = true;
}
/// <summary>
/// XML的序列化与反序列化
/// </summary>
public class XMLDemo : MonoBehaviour
{
private void Start()
{
//要存储为XML文件的文件流
Test test = new Test();
string path = Application.persistentDataPath + "/XMLTest01.xml";
print(path);
//流语句
//using加载文件 文件加载结束之后则会自动关闭
using(StreamWriter stream = new StreamWriter(path) )
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Test));
//将XML文件序列化 写入流中
//流根据配置的写入地址进行设置
xmlSerializer.Serialize(stream,test);
}
}
}
- 只能进行公共类型变量的存储
- 不支持字典存储
对应生成的XML文件如下图所示:

反序列化:
//反序列化
//判断是否存在要读取的XML文件
if (File.Exists(path))
{
using (StringReader reader = new StringReader(path))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Test));
Test testReaded=xmlSerializer.Deserialize(reader) as Test;
}
}
//tips:
//list对象中有默认值时候,反序列化时候会把默认值再次添加到list数组中
//可以理解为 当前反序列化时候要考察各种变量的默认值(初始值)
//如果过本身序列化时候会有new List(){1,2,3}之类的赋值操作
//则反序列化时会重新将1,2,3数值添加到list数组中,得到的
//反序列化结果中会有两个1,2,3 1,2,3 内容
Unity学习笔记--数据持久化XML文件(1)的更多相关文章
- Android(java)学习笔记185:xml文件生成
1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...
- Android(java)学习笔记128:xml文件生成
1.xml文件: 用元素描述数据,跨平台. 2.利用传统的方式创建xml文件,下面是一个案例: 设计思路:建立一个学生管理系统,创建xml文件保存学生信息: (1)首先是布局文件activity_ma ...
- Android学习笔记(9):使用XML文件和Java代码控制UI界面
Android推荐使用XML文件设置UI界面.然后用Java代码控制逻辑部分,这体现了MVC思想. MVC全名是Model View Controller.是模型(model)-视图(view)-控制 ...
- Android学习笔记之AndroidManifest.xml文件解析(转)
//自已备注: <?xml version="1.0" encoding="utf-8"?>//说明了版本号,字符集 <manifest xm ...
- Android学习笔记之AndroidManifest.xml文件解析
一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...
- Android学习笔记之AndroidManifest.xml文件解析(详解)
一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...
- Excel开发学习笔记:读取xml文件及csv文件
遇到一个数据处理自动化的问题,于是打算开发一个基于excel的小工具.在业余时间一边自学一边实践,抽空把一些知识写下来以备今后参考,因为走的是盲人摸象的野路子,幼稚与错误请多包涵. ).Split( ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
- php添加数据到xml文件的例子
php添加数据到xml文件中 时间:2015-12-17 06:30:37来源:网络 导读:php添加数据到xml文件中 xml文件:stu.xml: 复制代码代码如下: <?xml ver ...
- Java NIO 学习笔记(四)----文件通道和网络通道
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
随机推荐
- STM32CubeMX教程25 PWR 电源管理 - 睡眠、停止和待机模式
1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...
- clickhouse 优化实践,万级别QPS数据毫秒写入和亿级别数据秒级返回 | 京东云技术团队
1.背景 魔笛活动平台目前在采集每个活动的用户行为数据并进行查询,解决线上问题定位慢,响应不及时的问题,提升客诉的解决效率.目前每天采集的数据量5000万+,一个月的数据总量15亿+,总数据量40亿+ ...
- vue同步组件和异步组件的区别
异步组件 异步组件:只在组件需要渲染(组件第一次显示)的时候进行加载渲染并缓存,缓存是以备下次访问. Vue实现按需加载 在打包的时候,会打包成单独的js文件存储在static/js文件夹里面** 在 ...
- 【笔记】grafana v8.4.2 中如何设置曲线图的双坐标轴
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu 公众号:一本正经的瞎扯 这个话题当然很久就有人研究过了,只不过版本已经很老了,不适合新版本. 1 ...
- WebAssembly入门笔记[3]:利用Table传递引用
在<WebAssembly入门笔记[2]>中,我们介绍了如何利用Memory在作为宿主的JavaScript应用和wasm模块之间传递数据,但是Momory面向单纯二进制字节的读写在使用起 ...
- LyScript 插件实现自定义反汇编
LyScript 插件默认提供了一个get_disasm_code()方法可以直接获取到指定行数的反汇编代码,但如果需要自定义获取或者是需要自己封装一个反汇编方法,则你可以用如下两种方式来得到. 插件 ...
- CE修改器入门:查找共享代码
本关我们将学习共享代码,在C语言中角色属性都是以结构体的方式进行存储的,而结构体所存储的信息都是连续性的,这一关我们将会解释如何处理游戏中的共用代码,这种代码是通用在除了自己以外的其他同类型对像上的 ...
- Firefox浏览器的一些配置
一.在新标签页打开书签 1.打开Firefox浏览器,地址栏输入about:config. 2.选择"接受风险并继续". 3.搜索browser.tabs.loadBookmark ...
- 【C语言深度解剖】复数运算问题--【好题系列】学会这题,结构体没问题
复数问题 今天博主给大家带来一道博主自己在学校做到的一个题目.这个题目可以很好的加深我们对C语言结构体的理解,在这里分享给大家.学懂这题,我们的C语言结构体,没问题了! 本篇建议收藏后食用!以免退出找 ...
- OLED 驱动模块程序代码
1.前言 作为嵌入式软件开发,可能经常会使用单片机连接驱动显示屏,实现人机交互的功能,通常可选择的有 OLED 和 LCD 等,其中相关驱动代码例程网上更是数不胜数. 本文介绍的是 OLED, 常见代 ...