【unity数据持久化】XML数据管理器知识点

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 前言
        • XML是什么
        • 和游戏存储的关系
    • 🎶(==A==) XML文件格式
    • 🎶(==B==) XML基本规则
    • 🎶(==C==) XML属性
    • 🎶(==D==) 读取XML文件(c#)
    • 🎶(==E==) 读取XML文件中的信息(c#)
    • 🎶(==F==) 存储XML文件中的信息(c#)
    • 🎶(==G==) 修改XML文件中的信息(c#)
    • 🎶(==s==) XML 练习
          • XML编写练习
          • 读取练习
          • 存取练习
    • 🅰️


前言

XML是什么

XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求定义专属的标记。这是一种强大将数据存储在一个可以存储、搜索和共享的格式中的方法。最重要的是,因为 XML 的基本格式是标准化的,如果你在本地或互联网上跨系统或平台共享或传输 XML,由于标准化的 XML 语法,接收者仍然可以解析数据。

  • 全称可拓展标记语言extentsible markup language
  • XML是国际通用的
  • 它是被设计用来传输和存储数据的一种文本特殊格式

和游戏存储的关系

  • 游戏数据按照XML的格式标准——>存储在XML文档中
  • 再将XML文档存储在硬盘上或者传输给远端——达到数据持久化

一种存储和传输数据的选择
一种配置数据的方法

在这里插入图片描述


🎶(A XML文件格式


特点: 是一种树形结构

在这里插入图片描述

  • 注释的格式:——!–在这里写注释–

_________在这里插入图片描述

  • 固定的格式——?xml version =“1.0” encoding = “UTF-8”?
    在这里插入图片描述
  • UTF - 8是什么意思
    和ASCII码一样它也是一种编码格式只不过ASCII码是最原始的编码格式

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码.电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了


🎶(B XML基本规则


符号含义
&lt — <小于
&gt — >大于
&amp — &
&apos — ’单引号
&quot — "引号

注意:

1.每个元素都必须有关闭标签
2.元素命名规则基本遵照C#中变量名命名规则
3.XML标签要注意大小写
4.XML文档必须有根元素

在这里插入图片描述


🎶(C XML属性


  • 属性的特点

属性就是在元素标签后面空格 添加的内容
注意: 属性必须用引号包裹 单引号双引号都可以

  • 属性写法

    元素节点 —————————————> 属性
    

    作用都一样
    在这里插入图片描述

  • 格式验证方法

菜鸟教程XML 格式验证器

  • 练习

当出现没有变量名的数据时 就用变量类型名命名
在这里插入图片描述


🎶(D 读取XML文件(c#)


  • Xml文件存放位置

  • 1.只读不写的XML文件可以放在
    Resources或者StreamingAssets 文件夹下

  • 2.动态存储的XML文件放在
    Application.persistentDataPath 路径下

C#读取XML的方法有3种

  • 1.XmlDocument (把数据加载到内存中,使用XmlDocument类读取是较方便最容易理解和操作的方法)
  • 2.XmlTextReader (以流形式加载,内存占用更少,但是是单向只读,使用不是特别方便,除非有特殊需求,否则不会使用)
  • 3.Linq

XmlDocument

XmlDocument xml = new XmlDocument();

  • 1.xml文件名加载——存放在Resorces文件夹下的xml文件加载处理
        //为TextAsset  Resorces文件夹下的文本类TextAsset asset = Resources.Load<TextAsset>("xml文件名");print(asset.text);//加载为xml对象xml.LoadXml(asset.text);
  • 2.通过xml文件的路径加载——存放在StreamingAssets 文件夹下的xml文件加载处理
xml.Load(Application.streamingAssetsPath + "/xml文件名.xml");
//streamingAssetsPath 文件夹只读(移动端)pc(可读可写)

注意: 为什么不读Resource文件夹的路径,因为打包后它被压缩了读不到


🎶(E 读取XML文件中的信息(c#)


XmlDocument xml = new XmlDocument();

1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

2.获取xml当中的根节点:

  • XmlNode root = xml.SelectSingleNode(“根节点名”);

3.获取下面的子节点:

  • XmlNode nodeName = root.SelectSingleNode(“name”);

4.获取节点包裹的元素信息

  • nodeName.InnerText

5.获取节点属性信息

  • XmlNode nodeItem = root.SelectSingleNode(“Item”);
  • ①nodeItem.Attributes[“属性名”].Value
  • ②nodeItem.Attributes.GetNamedItem(“属性名”).Value

6.获取 一个节点下的同名节点的方法

为什么会有同名?
因为当出现没有变量名的数据时 就用变量类型名命名在这里插入图片描述

  • XmlNode nodeListInt = root.SelectSingleNode(“ListInt”);
  • XmlNodeList intList = nodeListInt.SelectNodes(“int”);

7.得到之后遍历

  • 迭代器遍历 foreach (XmlNode node in intList )
  • for循环遍历 for (int i = 0; i < intList .Count; i++)

8.得到子节点的子节点

  • 写法一
    XmlNode node = Xml.SelectSingleNode(“Root”).SelectSingleNode(“name”);
  • 写法二
    XmlNode node = Xml.SelectSingleNode(“Root/name”);


🎶(F 存储XML文件中的信息(c#)


  • 特殊文件夹读写性回顾

1.Resources 可读 不可写 打包后找不到
2.Application.streamingAssetsPath 可读 PC端可写 找得到
3.Application.dataPath 打包后找不到
4.Application.persistentDataPath 可读可写找得到

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


1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

通过代码API创建XML信息,不需要手动编写的流程

  • 0.及记录存储文件夹信息的路径
  string path = Application.persistentDataPath + "/要创建的文件夹名.xml";
  • 1.创建文本对象

      XmlDocument xml = new XmlDocument();
    
  • 2.添加固定版本信息

//相当于就是创建<?xml version="1.0" encoding="UTF-8"?>这句XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");//创建完成过后 要添加进入 文本对象中xml.AppendChild(xmlDec);
  • 3. 添加根节点
  XmlElement root = xml.CreateElement("Root");xml.AppendChild(root);
  • 4.为根节点添加子节点
     XmlElement name = xml.CreateElement("name");name.InnerText = "孙悟空";root.AppendChild(name);XmlElement age = xml.CreateElement("age");atk.InnerText = "10";root.AppendChild(age);XmlElement listInt = xml.CreateElement("listInt");//子节点里面加子节点组for (int i = 1; i <= 3; i++){XmlElement childNode = xml.CreateElement("int");childNode.InnerText = i.ToString();listInt.AppendChild(childNode);}root.AppendChild(listInt);
  • 5.添加属性
   XmlElement itemList = xml.CreateElement("itemList");for (int i = 1; i <= 3; i++){XmlElement childNode = xml.CreateElement("Item");//添加属性childNode.SetAttribute("id", i.ToString());childNode.SetAttribute("num", (i * 10).ToString());itemList.AppendChild(childNode);}root.AppendChild(itemList);
  • 6.保存

         xml.Save(path);
    

🎶(G 修改XML文件中的信息(c#)


1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

string path = Application.persistentDataPath + “/要创建的文件夹名.xml”;


  • 1.判断是否存在文件

File.Exists(path)

  • 2.加载XML文件API

newXml.Load(path);

【newXml -> XmlDocument类】

  • 3.创建节点

newXml.CreateElement(“节点名字”);

  • 5.增加子节点

root.AppendChild(node)

  • 6.移除子节点

root.RemoveChild(node);
【root -> XmlElemen节点类】

   if( File.Exists(path) ){//加载      newXml.Load(path);//移除XmlNode node;node = newXml.SelectSingleNode("Root/atk");//得到父节点XmlNode root2 = newXml.SelectSingleNode("Root");//移除子节点root2.RemoveChild(node);//添加节点XmlElement speed = newXml.CreateElement("moveSpeed");speed.InnerText = "20";root2.AppendChild(speed);//记得存newXml.Save(path);}

🎶(s XML 练习


XML编写练习

当出现没有变量名的数据时 就用变量类型名命名
在这里插入图片描述

读取练习
//将一个和PlayerInfo相同信息的XML文件的值读取出来赋给另一个对象
public class Item
{public int id;public int num;
}public class PlayerInfo
{public string name;public int atk;public int def;public float moveSpeed;public float roundSpeed;public Item weapon;public List<int> listInt;public List<Item> itemList;public Dictionary<int, Item> itemDic;public void LoadData(string fileName){//加载XML文件信息XmlDocument xml = new XmlDocument();//加载xml.Load(Application.streamingAssetsPath + "/" + fileName + ".xml");//从文件中加载出具体的数据//加载根节点 才能加载后面的内容XmlNode playerInfo = xml.SelectSingleNode("PlayerInfo");//通过根节点 去加载具体的信息this.name = playerInfo.SelectSingleNode("name").InnerText;this.atk = int.Parse(playerInfo.SelectSingleNode("atk").InnerText);this.def = int.Parse(playerInfo.SelectSingleNode("def").InnerText);this.moveSpeed = float.Parse(playerInfo.SelectSingleNode("moveSpeed").InnerText);this.roundSpeed = float.Parse(playerInfo.SelectSingleNode("roundSpeed").InnerText);XmlNode weaponNode = playerInfo.SelectSingleNode("weapon");this.weapon = new Item();this.weapon.id = int.Parse(weaponNode.SelectSingleNode("id").InnerText);this.weapon.num = int.Parse(weaponNode.SelectSingleNode("num").InnerText);XmlNode listIntNode = playerInfo.SelectSingleNode("listInt");XmlNodeList intList = listIntNode.SelectNodes("int");this.listInt = new List<int>();for (int i = 0; i < intList.Count; i++){this.listInt.Add(int.Parse(intList[i].InnerText));}XmlNode itemList = playerInfo.SelectSingleNode("itemList");XmlNodeList items = itemList.SelectNodes("Item");this.itemList = new List<Item>();foreach (XmlNode item in items){Item item2 = new Item();item2.id = int.Parse(item.Attributes["id"].Value);item2.num = int.Parse(item.Attributes["num"].Value);this.itemList.Add(item2);}XmlNode itemDic = playerInfo.SelectSingleNode("itemDic");XmlNodeList keyInt = itemDic.SelectNodes("int");XmlNodeList valueItem = itemDic.SelectNodes("Item");this.itemDic = new Dictionary<int, Item>();for (int i = 0; i < keyInt.Count; i++){int key = int.Parse(keyInt[i].InnerText);Item value = new Item();value.id = int.Parse(valueItem[i].Attributes["id"].Value);value.num = int.Parse(valueItem[i].Attributes["num"].Value);this.itemDic.Add(key, value);}}
}
存取练习
//封装一个将信息存到一个XML文件中的方法public void SaveData(string fileName){//决定存储路径string path = Application.persistentDataPath + "/" + fileName + ".xml";Debug.Log(Application.persistentDataPath);//5个步骤//1.创建我们的Xml文本 XmlDocument xml = new XmlDocument();//2.添加固定内容XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");xml.AppendChild(xmlDec);//3.添加根节点XmlElement playerInfo = xml.CreateElement("PlayerInfo");xml.AppendChild(playerInfo);//4.添加子节点 或者 属性相关XmlElement name = xml.CreateElement("name");name.InnerText = this.name;playerInfo.AppendChild(name);XmlElement atk = xml.CreateElement("atk");atk.InnerText = this.atk.ToString();playerInfo.AppendChild(atk);XmlElement def = xml.CreateElement("def");def.InnerText = this.def.ToString();playerInfo.AppendChild(def);XmlElement moveSpeed = xml.CreateElement("moveSpeed");moveSpeed.InnerText = this.moveSpeed.ToString();playerInfo.AppendChild(moveSpeed);XmlElement roundSpeed = xml.CreateElement("roundSpeed");roundSpeed.InnerText = this.roundSpeed.ToString();playerInfo.AppendChild(roundSpeed);//weaponXmlElement weapon = xml.CreateElement("weapon");XmlElement id = xml.CreateElement("id");id.InnerText = this.weapon.id.ToString();weapon.AppendChild(id);XmlElement num = xml.CreateElement("num");num.InnerText = this.weapon.num.ToString();weapon.AppendChild(num);playerInfo.AppendChild(weapon);//listIntXmlElement listInt = xml.CreateElement("listInt");for (int i = 0; i < this.listInt.Count; i++){XmlElement intNode = xml.CreateElement("int");intNode.InnerText = this.listInt[i].ToString();listInt.AppendChild(intNode);}playerInfo.AppendChild(listInt);//itemListXmlElement itemList = xml.CreateElement("itemList");for (int i = 0; i < this.itemList.Count; i++){XmlElement itemNode = xml.CreateElement("Item");itemNode.SetAttribute("id", this.itemList[i].id.ToString());itemNode.SetAttribute("num", this.itemList[i].num.ToString());itemList.AppendChild(itemNode);}playerInfo.AppendChild(itemList);//itemDicXmlElement itemDic = xml.CreateElement("itemDic");foreach (int key in this.itemDic.Keys){//keyXmlElement intNode = xml.CreateElement("int");intNode.InnerText = key.ToString();itemDic.AppendChild(intNode);//valueXmlElement itemNode = xml.CreateElement("Item");itemNode.SetAttribute("id", this.itemDic[key].id.ToString());itemNode.SetAttribute("num", this.itemDic[key].num.ToString());itemDic.AppendChild(itemNode);}playerInfo.AppendChild(itemDic);//5.存储xml.Save(path);}

🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/103667.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何更高效的写出更健全的代码,一篇文章教会你如何拥有一个良好的代码风格

前言&#xff1a;在平常的写代码的过程中&#xff0c;或多或少的遇到很多奇怪的 bug &#xff0c;尤其是一些大的程序&#xff0c;明明上一部分都是好好的&#xff0c;写下一块的时候突然多几百个 bug 的情况&#xff0c;然后这一块写完了后编译的时候直接傻眼了&#xff0c;看…

缓存穿透、缓存击穿和缓存雪崩

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱发博客的嗯哼&#xff0c;爱好Java的小菜鸟 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;社区论坛&#xff1a;希望大家能加入社区共同进步…

拼多多app商品详情接口 获取pdd商品主图价格销量库存信息

拼多多是中国一家知名的电商平台&#xff0c;以"社交团购新零售"的商业模式闻名&#xff0c;通过手机app和微信小程序等渠道提供商品销售和购物体验。平台上的商品种类丰富多样&#xff0c;涵盖了服装、家居、美妆、食品、数码电子等各个领域。 拼多多的商业模式主要…

Windows运行Spark所需的Hadoop安装

解压文件 复制bin目录 找到winutils-master文件hadoop对应的bin目录版本 全部复制替换掉hadoop的bin目录文件 复制hadoop.dll文件 将bin目录下的hadoop.dll文件复制到System32目录下 配置环境变量 修改hadoop-env.cmd配置文件 注意jdk装在非C盘则完全没问题&#xff0c;如果装在…

springboot+docker实现微服务的小例子

【任务】&#xff1a; 创建一个服务A&#xff1a;service_hello 创建一个服务B&#xff1a;service_name service_name负责提供一个api接口返回一个name字符串。 service_hello负责从这个接口获取name字符串&#xff0c;然后进行一个字符串拼接&#xff0c;在后面加一个hello&…

Module not found: Error: Can‘t resolve ‘vue-pdf‘ in ‘xxx‘

使用命令npm run serve时vue项目报错&#xff1a; Module not found: Error: Cant resolve vue-pdf in xxx 解决方案&#xff1a; 运行命令&#xff1a; npm install vue-pdf --save --legacy-peer-deps 即可解决。 再次顺利执行npm run serve

C语言暑假刷题冲刺篇——day4

目录 一、选择题 二、编程题 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C语言每日一练 ✨其他专栏&#xff1a;代码小游戏C语言初阶&#x1f91d;希望作者的文章能对你…

更改计算机睡眠时间

控制面板–>系统和安全–>电源选项下的更改计算机睡眠时间 如果关闭显示器时间小于使计算机进入睡眠状态时间&#xff0c;时间先到达关闭显示器时间&#xff0c;显示器关闭&#xff0c;这时电脑还在正常工作状态。如果此时敲击键盘显示器出现画面&#xff0c;无需输入密…

MySQL 主从配置

环境 centos6.7 虚拟机两台 主&#xff1a;192.168.23.160 从&#xff1a;192.168.23.163 准备 在两台机器上分别安装mysql5.6.23&#xff0c;安装完成后利用临时密码登录mysql数据修改root的密码&#xff1b;将my.cnf配置文件放至/etc/my.cnf&#xff0c;重启mysql服务进…

Spark Standalone环境搭建及测试

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 篇一&#xff1a;Linux系统下配置java环境 篇二&#xff1a;hadoop伪分布式搭建&#xff08;超详细&#xff09; 篇三&#xff1a;hadoop完全分布式集群搭建&#xff08;超详细&#xf…

解决生僻字,中兴新支点操作系统通过GB 18030-2022《中文编码字符集》认证

您认识上图中的这个字吗&#xff1f; 上面一个“鸟”&#xff0c;下面一个“甲”&#xff0c;这个字读“nia&#xff08;四声&#xff09;”。它是云南丽江傈僳族中一支氏族的姓氏。这个氏族以鸟为图腾。因信息系统中无法输入显示“nia”字&#xff0c;氏族里近700人不得不妥协…

python并发编程

一、程序提速的方法 二、python对并发编程的支持 多线程&#xff1a;threading&#xff0c;利用CPU和IO可以同时执行的原理&#xff0c;让CPU不会干巴巴等待IO完成&#xff1b;多进程&#xff1a;multiprocess&#xff0c;利用多核CPU的能力&#xff0c;真正的并行执行任务&am…

某多多商品平台数据采集

某多多商品平台数据采集 声明逆向目标寻找加密位置代码分析补环境补充内容声明 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者 无关,若有侵权,请私信我立即删除! 逆向目标 Anti-Content参数 寻找加密位置 先在控制台全局搜…

idea 新建servlet 访问提示404 WebServlet注解找不到包 报错

检查访问路径是否设置正确 如果设置为name “/testServlet”&#xff0c;则会404 WebServlet注解报错找不到包 检查是否引入了tomcat依赖包

基于GRU门控循环网络的时间序列预测matlab仿真,对比LSTM网络

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 LSTM: GRU 2.算法运行软件版本 matlab2022a 3.部分核心程序 %构建GRU网络模型 layers [ ...sequenceInputLayer(N_feature)gruLayer(N_hidden)f…

分析商务报表使用什么工具?

传统的BI分析商务报表存在的问题 随着数字化转型的深入推进&#xff0c;企业面临着海量数据的挑战和机遇。数据是企业的重要资产&#xff0c;能够帮助企业洞察市场动态、优化业务流程、提升客户满意度、创造竞争优势。然而&#xff0c;传统的BI&#xff08;商业智能&#xff0…

【腾讯云 TDSQL-C Serverless 产品测评】“橡皮筋“一样的数据库『MySQL高压篇』

【腾讯云 TDSQL-C Serverless 产品测评】"橡皮筋"一样的数据库 活动介绍服务一览何为TDSQL &#xff1f;Serverless 似曾相识&#xff1f; 降本增效&#xff0c;不再口号&#xff1f;动手环节 --- "压力"山大实验前瞻稍作简介资源扩缩范围&#xff08;CCU&…

浪潮信息企业级SSD:降本又增效?AIPR技术解决高并发读取性能大问题

NAND闪存作为一种非易失性存储介质&#xff0c;凭借其功耗低、重量轻、性能佳和断电后仍然能保存数据等特点&#xff0c;成为比硬盘驱动器更好的存储设备&#xff0c;非常适合作为便携设备的存储器来使用。 固态硬盘&#xff08;Solid State Disk&#xff0c;简称SSD&#xff0…

KUST_LI计算机视觉实验室服务器安装与管理

第一步&#xff1a;安装 Linux-Ubuntu系统 系统语言设置为英文 ENGLISH&#xff0c;防止系统 BUG&#xff1b;选择-清除整个磁盘并安装系统&#xff08;不要清除机械硬盘内容&#xff09;&#xff1b;设置用户名和密码&#xff0c;实验室统一时区设置为&#xff1a;中国上海其…

java八股文面试[java基础]——Object类有哪些方法

通过IDEA打开Object类就可以看到 &#xff08;1&#xff09;clone方法 保护方法&#xff0c;实现对象的浅复制&#xff0c;只有实现了Cloneable接口才可以调用该方法&#xff0c;否则抛出CloneNotSupportedException异常。 主要是JAVA里除了8种基本类型传参数是值传递&#xf…