6.存储和修改Xml文件

6.CSharp操作XML-存储和修改XML文件


6.1 知识点

Xml决定存储在哪个文件夹下

  • 注意:存储xml文件 在Unity中一定是使用各平台都可读可写可找到的路径
    • Resources 可读 不可写 打包加密后通过路径找不到 ×
    • Application.streamingAssetsPath 可读 PC端可写 但是其他平台不可写 打包加密后通过路径找得到 可以存些不会改的xml文件 ×
    • Application.dataPath 编辑器上操作看起来没什么问题 但是打包后找不到 ×
    • Application.persistentDataPath 可读可写 各个平台找得到 √
  • 准备好我们最终要存储的路径
    string path = Application.persistentDataPath + "/PlayerInfo2.xml";
    print(Application.persistentDataPath);//C:/Users/LinWentao/AppData/LocalLow/DefaultCompany/XML教程
    

存储xml文件

存储xml文件用到的关键类

XmlDocument Xml文档类 用于创建节点存储文件
XmlDeclaration Xml声明类 用于添加版本信息
XmlElement Xml元素类

存储xml文件具体的五个步骤

创建XmlDocument文档对象
//创建XmlDocument类文本对象 
//相当于新建xml文件
XmlDocument xmlDocument = new XmlDocument();
添加固定版本信息
XmlDocument.CreateXmlDeclaration方法 添加固定版本信息
//XmlDocument类中的CreateXmlDeclaration方法 添加固定版本信息
//这一句代码 相当于就是创建<?xmlDocument version="1.0" encoding="UTF-8"?>这句内容
XmlDeclaration xmlDec = xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "");
XmlDocument.AppendChild方法 把对象添加到xml文本对象中
//XmlDocument类中的AppendChild方法 把版本信息对象添加到xml文本对象中 
//创建完成过后 要添加进入 文本对象中
xmlDocument.AppendChild(xmlDec);
添加根节点
XmlDocument.CreateElement方法 创建根节点
//XmlDocument类中的CreateElement方法 添加根节点
XmlElement root = xmlDocument.CreateElement("Root");
//创建完成过后 要添加进入 文本对象中
xmlDocument.AppendChild(root);
为根节点添加子节点
XmlElement.SetAttribute方法 给节点设置属性和属性值
//为根节点添加子节点
//创建了了一个name子节点
XmlElement name = xmlDocument.CreateElement("name");

//XmlElement中的InnerText属性 设置包裹信息
name.InnerText = "林文韬";

//XmlElement类中的AppendChild方法 把子节点添加到xml文本对象中 
root.AppendChild(name);

//使用CreateElement方法在根节点下创建名称为“atk”的节点,并设置其InnerText(即节点内部的文本值)为“10”
XmlElement atk = xmlDocument.CreateElement("atk");
atk.InnerText = "10";
//将“atk”子节点添加至根节点“Root”中
root.AppendChild(atk);

//使用CreateElement方法在根节点下创建名称为“listInt”的XmlNode节点,并将三个名为“int”的子节点添加到该节点中。
XmlElement listInt = xmlDocument.CreateElement("listInt");
//遍历给listInt添加子节点
for (int i = 1; i <= 3; i++)
{
    //使用CreateElement方法在“listInt”节点下依次创建三个名为“int”的XmlElement节点
    XmlElement childNode = xmlDocument.CreateElement("int");

    //依次设置三个“int”子节点的InnerText值,分别为1、2、3
    childNode.InnerText = i.ToString();
    listInt.AppendChild(childNode);
}
//将“listInt”子节点添加至根节点“Root”中
root.AppendChild(listInt);

//使用CreateElement方法在根节点下创建名称为“itemList”的XmlElement节点,并将三个名为“Item”的子节点添加到该节点中,
XmlElement itemList = xmlDocument.CreateElement("itemList");
//遍历给itemList添加子节点
for (int i = 1; i <= 3; i++)
{
    //使用CreateElement方法在“itemList”节点下依次创建三个名为“Item”的XmlElement节点
    XmlElement childNode = xmlDocument.CreateElement("Item");

    //XmlElement中的SetAttribute方法 给节点设置属性和属性值
    //使用SetAttribute方法给每个“Item”节点设置两个属性,分别为“id”和“num”
    childNode.SetAttribute("id", i.ToString());
    childNode.SetAttribute("num", (i * 10).ToString());
    itemList.AppendChild(childNode);
}
//将“itemList”节点添加至根节点“Root”中
root.AppendChild(itemList);
保存
XmlDocument.Save方法 在指定路径保存xml文件
//XmlDocument类中的Save方法 在指定路径保存xml文件
xmlDocument.Save(path);
保存后的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <name>林文韬</name>
  <atk>10</atk>
  <listInt>
    <int>1</int>
    <int>2</int>
    <int>3</int>
  </listInt>
  <itemList>
    <Item id="1" num="10" />
    <Item id="2" num="20" />
    <Item id="3" num="30" />
  </itemList>
</Root>

修改xml文件

File.Exists方法 判断某路径是否存在文件

//File类中的Exists方法 判断路径是否存在
if ( File.Exists(path) )
{

}

加载后利用学过的方法修改xml文件

//File类中的Exists方法 判断路径是否存在
if ( File.Exists(path) )
{
    //2.加载后 直接添加节点 移除节点即可

    //创建xml文本对象 加载对应路径的xml文件
    XmlDocument newXml = new XmlDocument();
    newXml.Load(path);

    //修改就是在原有文件基础上 去移除 或者添加

    //移除节点

    XmlNode node;

    //可以在XmlNode中连续使用SelectSingleNode方法得到子节点
    node = newXml.SelectSingleNode("Root").SelectSingleNode("atk");

    //也可以通过/来区分父子节点的关系 得到子节点
    node = newXml.SelectSingleNode("Root/atk");

    //得到自己的父节点
    XmlNode root2 = newXml.SelectSingleNode("Root");

    //XmlNode类中的RemoveChild方法 移除子节点方法
    root2.RemoveChild(node);

    //添加节点

    //CreateElement创建一个节点
    XmlElement moveSpeed = newXml.CreateElement("moveSpeed");
    //设置包裹内容
    moveSpeed.InnerText = "20";
    //加到更节点
    root2.AppendChild(moveSpeed);

    //改了记得保存文档对象
    newXml.Save(path);
}

修改后的结果

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <name>林文韬</name>
  <listInt>
    <int>1</int>
    <int>2</int>
    <int>3</int>
  </listInt>
  <itemList>
    <Item id="1" num="10" />
    <Item id="2" num="20" />
    <Item id="3" num="30" />
  </itemList>
  <moveSpeed>20</moveSpeed>
</Root>

总结

  • 路径选取
    • 在运行过程中存储 只能往可写且能找到的文件夹存储
    • 故选择了Application.persistentDataPath
  • 存储xml关键类
    • XmlDocument 文件
      • 创建节点 CreateElement
      • 创建固定内容方法 CreateXmlDeclaration
      • 添加节点 AppendChild
      • 保存 Save
    • XmlDeclaration 版本
    • XmlElement 元素节点
      • 设置属性方法 SetAttribute
  • 修改
    • RemoveChild 移除节点
    • 可以通过 / 的形式来表示子节点的子节点

6.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

public class SaveXml : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 Xml决定存储在哪个文件夹下

        //注意:存储xml文件 在Unity中一定是使用各平台都可读可写可找到的路径
        // 1.Resources 可读 不可写 打包加密后通过路径找不到  ×
        // 2.Application.streamingAssetsPath 可读 PC端可写 但是其他平台不可写 打包加密后通过路径找得到 可以存些不会改的xml文件  ×
        // 3.Application.dataPath 编辑器上操作看起来没什么问题 但是打包后找不到  ×
        // 4.Application.persistentDataPath 可读可写 各个平台找得到   √

        //准备好我们最终要存储的路径
        string path = Application.persistentDataPath + "/PlayerInfo2.xml";
        print(Application.persistentDataPath);//C:/Users/LinWentao/AppData/LocalLow/DefaultCompany/XML教程

        #endregion

        #region 知识点二 存储xml文件

        //关键类 XmlDocument 用于创建节点 存储文件
        //关键类 XmlDeclaration 用于添加版本信息
        //关键类 XmlElement 节点类

        //存储有5步


        //1.创建文本对象

        //创建XmlDocument类文本对象 
        //相当于新建xml文件
        XmlDocument xmlDocument = new XmlDocument();


        //2.添加固定版本信息

        //XmlDocument类中的CreateXmlDeclaration方法 添加固定版本信息
        //这一句代码 相当于就是创建<?xmlDocument version="1.0" encoding="UTF-8"?>这句内容
        XmlDeclaration xmlDec = xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", "");

        //XmlDocument类中的AppendChild方法 把版本信息对象添加到xml文本对象中 
        //创建完成过后 要添加进入 文本对象中
        xmlDocument.AppendChild(xmlDec);


        //3.添加根节点

        //XmlDocument类中的CreateElement方法 添加根节点
        XmlElement root = xmlDocument.CreateElement("Root");
        //创建完成过后 要添加进入 文本对象中
        xmlDocument.AppendChild(root);


        //4.为根节点添加子节点

        //为根节点添加子节点
        //创建了了一个name子节点
        XmlElement name = xmlDocument.CreateElement("name");

        //XmlElement中的InnerText属性 设置包裹信息
        name.InnerText = "林文韬";

        //XmlElement类中的AppendChild方法 把子节点添加到xml文本对象中 
        root.AppendChild(name);

        //使用CreateElement方法在根节点下创建名称为“atk”的节点,并设置其InnerText(即节点内部的文本值)为“10”
        XmlElement atk = xmlDocument.CreateElement("atk");
        atk.InnerText = "10";
        //将“atk”子节点添加至根节点“Root”中
        root.AppendChild(atk);

        //使用CreateElement方法在根节点下创建名称为“listInt”的XmlNode节点,并将三个名为“int”的子节点添加到该节点中。
        XmlElement listInt = xmlDocument.CreateElement("listInt");
        //遍历给listInt添加子节点
        for (int i = 1; i <= 3; i++)
        {
            //使用CreateElement方法在“listInt”节点下依次创建三个名为“int”的XmlElement节点
            XmlElement childNode = xmlDocument.CreateElement("int");

            //依次设置三个“int”子节点的InnerText值,分别为1、2、3
            childNode.InnerText = i.ToString();
            listInt.AppendChild(childNode);
        }
        //将“listInt”子节点添加至根节点“Root”中
        root.AppendChild(listInt);

        //使用CreateElement方法在根节点下创建名称为“itemList”的XmlElement节点,并将三个名为“Item”的子节点添加到该节点中,
        XmlElement itemList = xmlDocument.CreateElement("itemList");
        //遍历给itemList添加子节点
        for (int i = 1; i <= 3; i++)
        {
            //使用CreateElement方法在“itemList”节点下依次创建三个名为“Item”的XmlElement节点
            XmlElement childNode = xmlDocument.CreateElement("Item");

            //XmlElement中的SetAttribute方法 给节点设置属性和属性值
            //使用SetAttribute方法给每个“Item”节点设置两个属性,分别为“id”和“num”
            childNode.SetAttribute("id", i.ToString());
            childNode.SetAttribute("num", (i * 10).ToString());
            itemList.AppendChild(childNode);
        }
        //将“itemList”节点添加至根节点“Root”中
        root.AppendChild(itemList);


        //5.保存

        //XmlDocument类中的Save方法 在指定路径保存xml文件
        xmlDocument.Save(path);

        #endregion

        #region 知识点三 修改xml文件

        //1.先判断是否存在文件

        //File类中的Exists方法 判断路径是否存在
        if ( File.Exists(path) )
        {
            //2.加载后 直接添加节点 移除节点即可

            //创建xml文本对象 加载对应路径的xml文件
            XmlDocument newXml = new XmlDocument();
            newXml.Load(path);

            //修改就是在原有文件基础上 去移除 或者添加

            //移除节点

            XmlNode node;

            //可以在XmlNode中连续使用SelectSingleNode方法得到子节点
            node = newXml.SelectSingleNode("Root").SelectSingleNode("atk");

            //也可以通过/来区分父子节点的关系 得到子节点
            node = newXml.SelectSingleNode("Root/atk");

            //得到自己的父节点
            XmlNode root2 = newXml.SelectSingleNode("Root");

            //XmlNode类中的RemoveChild方法 移除子节点方法
            root2.RemoveChild(node);

            //添加节点

            //CreateElement创建一个节点
            XmlElement moveSpeed = newXml.CreateElement("moveSpeed");
            //设置包裹内容
            moveSpeed.InnerText = "20";
            //加到更节点
            root2.AppendChild(moveSpeed);

            //改了记得保存文档对象
            newXml.Save(path);
        }

        #endregion

        #region 总结

        //1.路径选取
        //在运行过程中存储 只能往可写且能找到的文件夹存储
        //故 选择了Application.persistentDataPath

        //2.存储xml关键类
        //XmlDocument  文件  
        //   创建节点 CreateElement
        //   创建固定内容方法 CreateXmlDeclaration
        //   添加节点 AppendChild
        //   保存 Save
        //XmlDeclaration 版本
        //XmlElement 元素节点  
        //   设置属性方法SetAttribute

        //3.修改
        //RemoveChild移除节点
        //可以通过 /的形式 来表示 子节点的子节点 

        #endregion
    }

}

6.3 练习题

结合上一个知识点的练习题,实现将PlayerInfo数据存储到XML文件

在PlayerInfo类创建用XMl存储数据的方法,分五步骤存储xml文件

//定义一个名为 SaveData 的公共方法,参数为文件名字符串 fileName
public void SaveData(string fileName)
{
    //决定存储路径
    string path = Application.persistentDataPath + "/" + fileName + ".xml";

    //输出该XML文档将保存在何处。
    Debug.Log(Application.persistentDataPath);

    //初始化5步操作。

    //1.创建XmlDocument对象。稍后它将包含所需的Xml数据。
    XmlDocument xml = new XmlDocument();

    //2.使用CreateXmlDeclaration()方法创建XmlDeclaration对象声明文档类型和版本。
    XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
    //将XmlDeclaration对象添加到XmlDocument对象中。
    //这将把该声明作为XML文件的第一行。
    xml.AppendChild(xmlDec);

    //3.添加根节点
    //使用CreateElement()方法,创建一个根节点XmlElement对象并命名为“PlayerInfo”。
    XmlElement playerInfo = xml.CreateElement("PlayerInfo");
    //向XmlDocument对象添加根节点XmlElement对象“playerInfo”
    xml.AppendChild(playerInfo);

    //4.添加子节点 或者 属性相关

    //使用CreateElement方法创建Xml子项XmlElement对象并设置它们的InnerText值。
    //XmlElement对象表示不带数据的标记或元素。
    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);

    //创建XmlElement对象表示装备与其属性
    XmlElement 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);

    //创建XmlAttribute对象表示一个整数列表(listInt)
    XmlElement listInt = xml.CreateElement("listInt");
    for (int i = 0; i < this.listInt.Count; i++)
    {
        //使用CreateElement方法创建名为“int”的子节点,设置InnerText值并添加到根节点中的列表项。
        XmlElement intNode = xml.CreateElement("int");
        intNode.InnerText = this.listInt[i].ToString();
        listInt.AppendChild(intNode);
    }

    playerInfo.AppendChild(listInt);

    //构建名为$itemList的XmlElement对象,该对象将保存所有的Item项目 .
    XmlElement itemList = xml.CreateElement("itemList");

    for (int i = 0; i < this.itemList.Count; i++)
    {
        //使用CreateElement方法分别在itemList根节点下创建三个Xml子项<Element>对象。
        XmlElement itemNode = xml.CreateElement("Item");

        //谁每个XmlElement对象的ID和Num属性各自包含了itemList中的Item对象的ID属性和Num属性。
        itemNode.SetAttribute("id", this.itemList[i].id.ToString());
        itemNode.SetAttribute("num", this.itemList[i].num.ToString());

        //将三个XmlElement对象都添加到itemList节点之下。
        itemList.AppendChild(itemNode);
    }

    playerInfo.AppendChild(itemList);

    //创建一个名为itemDict的XmlElement对象,该对象将保存所有Item相关数据
    XmlElement itemDic = xml.CreateElement("itemDic");

    foreach (int key in this.itemDic.Keys)
    {
        //分别实例化intNode和itemNode对象来存储Dictionary<int,Item>对象的键值对数据。
        XmlElement intNode = xml.CreateElement("int");
        intNode.InnerText = key.ToString();   //key作为标记内部的InnerText值

        //itemNode的ID属性和Num属性包含字典项的Id属性和Num属性。
        XmlElement itemNode = xml.CreateElement("Item");
        itemNode.SetAttribute("id", this.itemDic[key].id.ToString());
        itemNode.SetAttribute("num", this.itemDic[key].num.ToString());

        //添加这两个XmlElement对象到XmlDocument对象中。
        itemDic.AppendChild(intNode);
        itemDic.AppendChild(itemNode);
    }

    //将此XmlElement对象添加到根XmlElement对象之下
    playerInfo.AppendChild(itemDic);

    //5.使用XmlDocument类的Save()方法将生成的XML文本与指定路径path的文件进行存储。
    xml.Save(path);
}

在测试类修改PlayerInfo对象的内容测试保存

p.name = "林文韬修改后的内容";
p.listInt.Add(99);

Item i = new Item();
i.id = 666;
i.num = 999;
p.itemList.Add(i);

p.itemDic.Add(250, i);

p.SaveData("PlayerInfo");

6.4 练习题代码

PlayerInfo

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEngine;

// 定义Item类
public class Item
{
    public int id;
    public int num;
}

//定义一个名为 PlayerInfo 的公共类
public class PlayerInfo
{
    //以下为 PlayerInfo 类的成员变量
    //玩家昵称,字符串类型
    public string name;
    //攻击力,整型
    public int atk;
    //防御力,整型
    public int def;
    //移动速度,浮点型
    public float moveSpeed;
    //回合速度,浮点型
    public float roundSpeed;
    //武器信息,Item 类型
    public Item weapon;
    //整数列表,使用 List<int> 实现
    public List<int> listInt;
    //物品列表,使用 List<Item> 实现
    public List<Item> itemList;
    //物品字典,使用 Dictionary<int, Item> 实现
    public Dictionary<int, Item> itemDic;

    //定义一个名为 LoadData 的公共方法,参数为文件名字符串 fileName
    public void LoadData(string fileName)
    {
        //构建文件路径,用于读取玩家存档数据
        string path = Application.persistentDataPath + "/" + fileName + ".xml";

        //如果存档文件不存在,则从默认资源中获取数据
        if (!File.Exists(path))
        {
            path = Application.streamingAssetsPath + "/" + fileName + ".xml";
        }

        //加载 XML 文件信息
        XmlDocument xml = new XmlDocument();
        //加载
        xml.Load(path);

        //从文件中加载出具体的数据

        //加载根节点才能加载后面的内容
        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 itemListNode = playerInfo.SelectSingleNode("itemList");
        XmlNodeList items = itemListNode.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 itemDicNode = playerInfo.SelectSingleNode("itemDic");
        XmlNodeList keyInt = itemDicNode.SelectNodes("int");
        XmlNodeList valueItem = itemDicNode.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);
        }
    }

    //定义一个名为 SaveData 的公共方法,参数为文件名字符串 fileName
    public void SaveData(string fileName)
    {
        //决定存储路径
        string path = Application.persistentDataPath + "/" + fileName + ".xml";

        //输出该XML文档将保存在何处。
        Debug.Log(Application.persistentDataPath);

        //初始化5步操作。

        //1.创建XmlDocument对象。稍后它将包含所需的Xml数据。
        XmlDocument xml = new XmlDocument();

        //2.使用CreateXmlDeclaration()方法创建XmlDeclaration对象声明文档类型和版本。
        XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
        //将XmlDeclaration对象添加到XmlDocument对象中。
        //这将把该声明作为XML文件的第一行。
        xml.AppendChild(xmlDec);

        //3.添加根节点
        //使用CreateElement()方法,创建一个根节点XmlElement对象并命名为“PlayerInfo”。
        XmlElement playerInfo = xml.CreateElement("PlayerInfo");
        //向XmlDocument对象添加根节点XmlElement对象“playerInfo”
        xml.AppendChild(playerInfo);

        //4.添加子节点 或者 属性相关

        //使用CreateElement方法创建Xml子项XmlElement对象并设置它们的InnerText值。
        //XmlElement对象表示不带数据的标记或元素。
        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);

        //创建XmlElement对象表示装备与其属性
        XmlElement 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);

        //创建XmlAttribute对象表示一个整数列表(listInt)
        XmlElement listInt = xml.CreateElement("listInt");
        for (int i = 0; i < this.listInt.Count; i++)
        {
            //使用CreateElement方法创建名为“int”的子节点,设置InnerText值并添加到根节点中的列表项。
            XmlElement intNode = xml.CreateElement("int");
            intNode.InnerText = this.listInt[i].ToString();
            listInt.AppendChild(intNode);
        }

        playerInfo.AppendChild(listInt);

        //构建名为$itemList的XmlElement对象,该对象将保存所有的Item项目 .
        XmlElement itemList = xml.CreateElement("itemList");

        for (int i = 0; i < this.itemList.Count; i++)
        {
            //使用CreateElement方法分别在itemList根节点下创建三个Xml子项<Element>对象。
            XmlElement itemNode = xml.CreateElement("Item");

            //谁每个XmlElement对象的ID和Num属性各自包含了itemList中的Item对象的ID属性和Num属性。
            itemNode.SetAttribute("id", this.itemList[i].id.ToString());
            itemNode.SetAttribute("num", this.itemList[i].num.ToString());

            //将三个XmlElement对象都添加到itemList节点之下。
            itemList.AppendChild(itemNode);
        }

        playerInfo.AppendChild(itemList);

        //创建一个名为itemDict的XmlElement对象,该对象将保存所有Item相关数据
        XmlElement itemDic = xml.CreateElement("itemDic");

        foreach (int key in this.itemDic.Keys)
        {
            //分别实例化intNode和itemNode对象来存储Dictionary<int,Item>对象的键值对数据。
            XmlElement intNode = xml.CreateElement("int");
            intNode.InnerText = key.ToString();   //key作为标记内部的InnerText值

            //itemNode的ID属性和Num属性包含字典项的Id属性和Num属性。
            XmlElement itemNode = xml.CreateElement("Item");
            itemNode.SetAttribute("id", this.itemDic[key].id.ToString());
            itemNode.SetAttribute("num", this.itemDic[key].num.ToString());

            //添加这两个XmlElement对象到XmlDocument对象中。
            itemDic.AppendChild(intNode);
            itemDic.AppendChild(itemNode);
        }

        //将此XmlElement对象添加到根XmlElement对象之下
        playerInfo.AppendChild(itemDic);

        //5.使用XmlDocument类的Save()方法将生成的XML文本与指定路径path的文件进行存储。
        xml.Save(path);
    }
}

Test

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        PlayerInfo p = new PlayerInfo();
        p.LoadData("PlayerInfo");

        p.name = "林文韬修改后的内容";
        p.listInt.Add(99);
        
        Item i = new Item();
        i.id = 666;
        i.num = 999;
        p.itemList.Add(i);

        p.itemDic.Add(250, i);

        p.SaveData("PlayerInfo");
    }
}

PlayerInfo.xml

<?xml version="1.0" encoding="UTF-8"?>
<PlayerInfo>
  <name>林文韬修改后的内容</name>
  <atk>10</atk>
  <def>5</def>
  <moveSpeed>20</moveSpeed>
  <roundSpeed>20</roundSpeed>
  <weapon>
    <id>1</id>
    <num>1</num>
  </weapon>
  <listInt>
    <int>1</int>
    <int>2</int>
    <int>3</int>
    <int>99</int>
  </listInt>
  <itemList>
    <Item id="1" num="10" />
    <Item id="2" num="20" />
    <Item id="3" num="30" />
    <Item id="4" num="40" />
    <Item id="666" num="999" />
  </itemList>
  <itemDic>
    <int>1</int>
    <Item id="1" num="1" />
    <int>2</int>
    <Item id="2" num="1" />
    <int>3</int>
    <Item id="3" num="1" />
    <int>250</int>
    <Item id="666" num="999" />
  </itemDic>
</PlayerInfo>


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏