【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.mzph.cn/news/50782.shtml

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

相关文章

Wireshark数据抓包分析之互联网协议(IP协议)

一、实验目的&#xff1a; 通过wireshark抓包分析IP协议的具体内容 二、预备知识&#xff1a; 1.IP地址存在的意义&#xff0c;就是为了弥补mac地址的不足&#xff0c;用于区分不同的网络 2.还有一些ip协议、ip数据包这些东西 三、网络拓扑 四、实验过程&#xff1a; part1&…

如何在 Kubernetes 中借助 Service 实现灰度发布和蓝绿发布

前言 部署在 Kubernetes 集群中的应用&#xff0c;在升级发布时可能会存在的问题&#xff1a; 1&#xff0c;由于 Kuberneter 底层 Pod 容器生命周期与网络组件生命周期是异步管理的&#xff0c;在升级时如果没有处理好应用优雅退出的问题&#xff0c;就很容易导致 http 访问请…

四川玖璨电子商务有限公司:怎么拉升抖店体验分

抖音是中国最受欢迎的短视频分享平台之一&#xff0c;而在抖音上开设自己的抖店成为许多电商从业者的选择。为了提高抖店的曝光度和用户体验&#xff0c;抖店体验分成为了一个重要的指标。在本文中&#xff0c;小编将从两个方面来讨论怎么拉升抖店体验分&#xff0c;包括影响因…

Flink的Standalone部署实战

在Flink是通用的框架&#xff0c;以混合和匹配的方式支持部署不同场景&#xff0c;而Standalone单机部署方便快速部署&#xff0c;记录本地部署过程&#xff0c;方便备查。 环境要求 1&#xff09;JDK1.8及以上 2&#xff09;flink-1.14.3 3&#xff09;CentOS7 Flink相关信…

第 7 章 排序算法(4)(插入排序)

7.7插入排序 7.7.1插入排序法介绍: 插入式排序属于内部排序法&#xff0c;是对于欲排序的元素以插入的方式找寻该元素的适当位置&#xff0c;以达到排序的目的。 7.7.2插入排序法思想: 插入排序&#xff08;Insertion Sorting&#xff09;的基本思想是&#xff1a;把n个待排…

点云平面拟合和球面拟合

一、介绍 In this tutorial we learn how to use a RandomSampleConsensus with a plane model to obtain the cloud fitting to this model. 二、代码 #include <iostream> #include <thread> #include <pcl/point_types.h> #include <pcl/common/io.…

Android GreenDao数据库升级(附Demo)

前言 大家好久不见&#xff0c;一转眼马上八月份下旬了&#xff0c;最近由于工作比较忙&#xff0c;没时间给大家更新博文。百忙之中抽出时间&#xff0c;给大家来更新一篇关于GreenDao3数据库的升级。 关于GreenDao的详细介绍以及一些逻辑性的增、删、改、查等&#xff0c;可以…

Nevron Open Vision for .NET Crack

Nevron Open Vision for .NET Crack NET Vision是一个用于生成具有数据可视化功能的强大数据表示应用程序的包。该套件具有用于.NET的Nevron Chart、用于.NET的Nevron Diagram和用于.NET的Nevron User Interface。精心设计的对象模型、许多功能和卓越的演示使复杂数据的可视化变…

git操作:将一个仓库的分支提交到另外一个仓库分支

这个操作&#xff0c;一般是同步不同网站的同个仓库&#xff0c;比如说gitee 和github。某个网站更新了&#xff0c;你想同步他的分支过来。然后基于分支开发或者其它。 操作步骤 1.本地先clone 你自己的仓库。也就是要push 分支的仓库。比如A仓库&#xff0c;把B仓库分支&am…

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测

分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 目录 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 分类预测 | MATLAB实现S4VM半监督支持向量机二分类预测 程序设计 完整源码和数据获取方式&#xff1a; …

使用端口映射实现Spring Boot服务端接口的公网远程调试:详细配置与步骤解析

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

解决npm安装依赖失败,node和node-sass版本不匹配的问题

npm安装依赖报错&#xff1a; npm ERR! cb() never called! npm ERR! This is an error with npm itself. 一. 问题描述 用npm安装依赖报错&#xff1a; npm ERR! cb() never called! npm ERR! This is an error with npm itself. Please report this error at: npm ERR! …

【数据结构】C语言实现栈(详细解读)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现栈 目录 什么是栈 栈的概念及结构 实现栈的方式 链表的优缺点: 顺序表的优缺点: 栈…

深入探索快速排序:高效分而治之的算法

1. 引言&#xff1a;快速排序的背景与重要性 快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;以其出色的性能和普适性而受到广泛关注。它利用了分而治之的思想&#xff0c;通过将数组分割成较小的子数组&#xff0c;并将这些子数组分别排序来实现…

使用 Amazon Redshift Serverless 和 Toucan 构建数据故事应用程序

这是由 Toucan 的解决方案工程师 Django Bouchez与亚马逊云科技共同撰写的特约文章。 带有控制面板、报告和分析的商业智能&#xff08;BI&#xff0c;Business Intelligence&#xff09;仍是最受欢迎的数据和分析使用场景之一。它为业务分析师和经理提供企业的过去状态和当前状…

MQ消息队列(主要介绍RabbitMQ)

消息队列概念&#xff1a;是在消息的传输过程中保存消息的容器。 作用&#xff1a;异步处理、应用解耦、流量控制..... RabbitMQ&#xff1a; SpringBoot继承RabbitMQ步骤&#xff1a; 1.加入依赖 <dependency><groupId>org.springframework.boot</groupId&g…

隧道HTTP具备的条件

作为一名专业的爬虫代理供应商&#xff0c;我们都知道使用代理是保证爬虫的高效性和稳定性的重要手段之一。而隧道代理则是近年来备受推崇的一种代理形式&#xff0c;它通过将请求通过隧道传输&#xff0c;可以有效地隐藏爬虫的真实IP地址&#xff0c;提高爬虫的反爬能力。 在…

ConfigMap(可变应用配置管理)

实验环境 实验环境&#xff1a; 1、win10,vmwrokstation虚机&#xff1b; 2、k8s集群&#xff1a;3台centos7.6 1810虚机&#xff0c;1个master节点,2个node节点k8s version&#xff1a;v1.22.2containerd://1.5.5实验软件(无) 1 基础知识 1.1 什么是ConfigMap(可变配置管理…

matlab工具箱Filter Designer设计butterworth带通滤波器

1、在matlab控制界面输入fdatool; 2、在显示的界面中选择合适的参数&#xff1b;本实验中采样频率是200&#xff0c;低通30hz&#xff0c;高通60hz,点击butterworth滤波器。 3、点击设计滤波器按钮后&#xff0c;在生成的界面点击红框按钮&#xff0c;可生成simulink模型到当前…

Linux下彻底卸载jenkins

文章目录 1、停服务进程2、查找安装目录3、删掉相关目录4、确认已完全删除 1、停服务进程 查看jenkins服务是否在运行&#xff0c;如果在运行&#xff0c;停掉 ps -ef|grep jenkins kill -9 XXX2、查找安装目录 find / -name "jenkins*"3、删掉相关目录 # 删掉相…