• Unity数据持久化——XML


    1.XML概述

    1.XML是什么?

    全称:可拓展标记语言(EXtensible Markup Language)

    XML是国际通用的

    它是被设计来用于传输和存储数据的一种文本特殊格式

    文件后缀一般为.xml

    2.如何理解不同后缀的文件

    文件后缀名决定了文件的格式

    不同的软件可以根据后缀名用来判断文件的类型,并且在打开文件时以特定的读取规则去解析它

    文件后缀名是人为定的规则,可以有无数种,可以自定义

    3.我们一般使用XML文件来记录和传输数据

    XML文档就是使用XML格式配置填写的文档后缀一般为.xml

    我们在游戏中可以把游戏数据按照XML的格式标准,存储在XML文档中,再将XML文档存储在硬盘上或者传输给远端,达到数据持久化的目的

    2.XML文件格式

    1.XML基本语法

    只要能打开文档的软件都能打开 XML 文件,常用的一些打开 XML 文件的方式 :

    1. 系统自带——记事本、写字板
    2. 专用 XML 文本编辑器——XMLSpear、STDU XML Editor 等等
    3. 通用文本编辑器——Sublime Text 等等
    4. VS Code

    XML 格式是一种树形结构的根结点

    1.创建XML

    直接右键创建文本,后缀改为.xml,选择自己喜欢的用于编辑 xml 的软件,进行文本编辑

    2.语法规则

    1.注释

    2.开头

    1. "1.0" encoding="UTF-8"?>

     3.内容

    1. <PlayerInfo>
    2. <name>xxxname>
    3. <age>18age>
    4. <sex>truesex>
    5. <listInt>
    6. <int>1int>
    7. <int>2int>
    8. <int>3int>
    9. listInt>
    10. PlayerInfo>

     4.基本规则

    • 每个元素都必须有关闭标签
    • 元素命名规则基本遵照 C# 中变量名命名规则
    • XML 标签对大小写敏感
    • XML 文档必须有根元素
    • 特殊的符号应该用实体引用

            <        ——>     < (小于)

            >       ——>     > (大于)
            &   ——>     &(和号)
            &apos  ——>      ' (单引号)
            "   ——>     " (引号)

    3.XML属性

    1.属性语法

    属性就是在元素标签后面的空格添加的内容

    注意:属性必须引用引号包裹 可以是单引号,也可以是双引号

    <Friend name="xxx" age='18'>friendFriend>

     如果使用属性记录信息,不想使用元素记录信息,就可以不写元素

    <Friend name="xxx">

    2.属性和元素结点的区别

    ​ 属性和元素节点只是写法上的区别而已,我们可以选择自己喜欢的方式来记录数据

    3.如何检查语法错误

    • 元素标签必须配对
    • 属性必须有引号
    • 注意命名

    3.C#读取存储XML

    1.XML文件存放位置

    1.只读不写的 XML

    放在 Resouces 或者 StreamingAssets(路径获取:Application.streamingAssetsPath) 文件夹下

    2.动态存储的 XML

    放在 Application.persistentDataPath 路径下

    2.读取XML文件

    C# 读取 XML 的方法有几种:

    1. XmlDocument (把数据加载到内存中,方便读取)
    2. XmlTextReader (以流形式加载,内存占用更少,但是是单向只读,使用不是特别方便,除非有特殊需求,否则不会使用)
    3. Linq

    使用 XmlDocument 类读取是较方便最容易理解和操作的方法

    示例:XML文件

    1. "1.0" encoding="UTF-8"?>
    2. <Root>
    3. <name>xxxname>
    4. <age>18age>
    5. <Item id="1" num="10"/>
    6. <Friend>
    7. <name>张三name>
    8. <age>19age>
    9. Friend>
    10. <Friend>
    11. <name>李四name>
    12. <age>20age>
    13. Friend>
    14. Root>

     1.读取 xml 文件信息

    1. XmlDocument xml = new XmlDocument();
    2. 读取文本方式1
    3. xml.LoadXml(传入xml文本字符串)
    4. 读取文本方式2
    5. xml.Load(传入路径)
    1. using System.Xml;
    2. XmlDocument xml = new XmlDocument();
    3. // 通过XmlDocument读取xml文件 有两个API
    4. // 1.直接根据xml字符串内容 来加载xml文件
    5. // 存放在Resorces文件夹下的xml文件加载处理
    6. TextAsset asset = Resources.Load("TestXml");
    7. print(asset.text);
    8. // 通过这个方法 就能够翻译字符串为xml对象
    9. xml.LoadXml(asset.text);
    10. // 2.是通过xml文件的路径去进行加载
    11. // 存放在StreamingAssets文件夹下的xml文件加载处理
    12. xml.Load(Application.streamingAssetsPath + "/TestXml.xml");

    2.读取元素和属性信息 

    节点信息类:XmlNode 单个节点信息类

    节点列表信息:XmlNodeList 多个节点信息类 

    1. 获取单个节点:
    2. XmlNode node = xml.SelectSingleNode(节点名);
    3. 获取多个节点:
    4. XmlNodeList nodeList = xml.SelectNodes(节点名);
    5. 获取节点元素内容:node.InnerText
    6. 获取节点元素属性:
    7. 1.item.Attributes["属性名"].Value;
    8. 2.item.Attributes.GetNamedItem("属性名").Value;
    9. 通过迭代器遍历或者循环遍历XmlNodeList对象 可以获取到各单个元素节点
    1. // 获取xml当中的根节点
    2. XmlNode root = xml.SelectSingleNode("Root");
    3. // 再通过根节点 去获取下面的子节点
    4. XmlNode nodeName = root.SelectSingleNode("name");
    5. // 如果想要获取节点包裹的元素信息 直接 .InnerText
    6. print(nodeName.InnerText);
    7. XmlNode nodeAge = root.SelectSingleNode("age");
    8. print(nodeAge.InnerText);
    9. XmlNode nodeItem = root.SelectSingleNode("Item");
    10. // 第一种方式 直接 中括号获取信息
    11. print(nodeItem.Attributes["id"].Value);
    12. print(nodeItem.Attributes["num"].Value);
    13. // 第二种方式
    14. print(nodeItem.Attributes.GetNamedItem("id").Value);
    15. print(nodeItem.Attributes.GetNamedItem("num").Value);
    16. // 这里是获取 一个节点下的同名节点的方法
    17. XmlNodeList friendList = root.SelectNodes("Friend");
    18. // 遍历方式一:迭代器遍历
    19. foreach (XmlNode item in friendList)
    20. {
    21. print(item.SelectSingleNode("name").InnerText);
    22. print(item.SelectSingleNode("age").InnerText);
    23. }
    24. // 遍历方式二:通过for循环遍历
    25. // 通过XmlNodeList中的 成员变量 Count可以得到 节点数量
    26. for (int i = 0; i < friendList.Count; i++)
    27. {
    28. print(friendList[i].SelectSingleNode("name").InnerText);
    29. print(friendList[i].SelectSingleNode("age").InnerText);
    30. }

    3.存储修改XML文件

    1.决定存储在哪个文件夹下

     存储 xml 文件,在 Unity 中一定是使用各平台都可读可写可找到的路径

    Application.persistentDataPath

    2.存储 XML 文件

    关键类 XmlDocument:用于创建节点 存储文件

    关键类 XmlDeclaration:用于添加版本信息

    关键类 XmlElement:节点类

    存储有 5 步:

    第一步:创建文本对象

    XmlDocument xml = new XmlDocument();

    第二步:添加固定版本信息

    1. // 这一句代码 相当于就是创建这句内容
    2. // 第三个参数传空串就可以了,目前不用管
    3. XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
    4. // 创建完成过后 要添加进入 文本对象中
    5. xml.AppendChild(xmlDec);

    第三步:添加根节点

    1. XmlElement root = xml.CreateElement("Root");
    2. xml.AppendChild(root);

    第四步:为根节点添加子节点

    1. // 加了一个 name子节点
    2. XmlElement name = xml.CreateElement("name");
    3. name.InnerText = "xxx";
    4. root.AppendChild(name);
    5. XmlElement atk = xml.CreateElement("atk");
    6. atk.InnerText = "10";
    7. root.AppendChild(atk);
    8. XmlElement listInt = xml.CreateElement("listInt");
    9. for (int i = 1; i <= 3; i++)
    10. {
    11. XmlElement childNode = xml.CreateElement("int");
    12. childNode.InnerText = i.ToString();
    13. listInt.AppendChild(childNode);
    14. }
    15. root.AppendChild(listInt);
    16. XmlElement itemList = xml.CreateElement("itemList");
    17. for (int i = 1; i <= 3; i++)
    18. {
    19. XmlElement childNode = xml.CreateElement("Item");
    20. // 添加属性
    21. childNode.SetAttribute("id", i.ToString());
    22. childNode.SetAttribute("num", (i * 10).ToString());
    23. itemList.AppendChild(childNode);
    24. }
    25. root.AppendChild(itemList);

    第五步:保存

    xml.Save(path);

    3.修改 XML 文件 

    1. using System.IO;
    2. // 1.先判断是否存在文件
    3. if( File.Exists(path) )
    4. {
    5. // 2.加载后 直接添加节点 移除节点即可
    6. XmlDocument newXml = new XmlDocument();
    7. newXml.Load(path);
    8. // 修改就是在原有文件基础上 去移除 或者添加
    9. // 移除
    10. // 这种是一种简便写法 通过 "/" 来区分父子关系
    11. XmlNode node = newXml.SelectSingleNode("Root/atk");
    12. // XmlNode node = newXml.SelectSingleNode("Root").SelectSingleNode("atk");
    13. // 得到自己的父节点
    14. XmlNode root2 = newXml.SelectSingleNode("Root");
    15. // 移除子节点方法
    16. root2.RemoveChild(node);
    17. // 直接删除自己
    18. // node.ParentNode.RemoveChild(node);
    19. // 添加节点
    20. XmlElement speed = newXml.CreateElement("moveSpeed");
    21. speed.InnerText = "20";
    22. root2.AppendChild(speed);
    23. // 改了记得存
    24. newXml.Save(path);
    25. }
  • 相关阅读:
    QT_C++_多线程
    VR、AR、MR、XR到底都是什么?有什么区别
    SpringBoot Kafka消费者 多kafka配置
    可变参数模板
    力扣541-反转字符串2——双指针法
    易点易动固定资产管理系统:提升企业固定资产领用效率的智慧选择
    MTK平台双击Power打开Camera的简单流程
    DRF03-权限与分页
    基于springboot的社区流浪动物救助管理系统(前端+后端)
    Docker如何进行实践应用?
  • 原文地址:https://blog.csdn.net/weixin_45274937/article/details/126906776