【Unity数据持久化】Ixmllserializable接口的使用

一、Ixmllserializable是什么?

是C#中的XmlSerializer中提供了可拓展内容
可以让一些无法被序列化和反序列化的特殊类能被序列化(如Dictionary)
让特殊类继承Ixmllserializable接口,实现其中的方法即可

二、自定义类实践

实践前须知:
将演示对这个数据结构类进行序列化和反序列化

public class PlayerInfo
{
    public int lv;      //等级
    public string name; //名字
}

在这里插入图片描述
直接上代码:

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using UnityEngine;
//准备一个自定义类,用来被序列化
//  继承IXmlSerializable接口,继承此接口后,将会使用我们自定义的序列化规则
public class PlayerInfo : IXmlSerializable
{
    public int lv;
    public string name;

    //实现继承IXmlSerializable接口中的三个方法
    /// <summary>
    /// 方法1
    /// </summary>
    /// <returns></returns>
    public XmlSchema GetSchema()
    {
        //直接返回空即可
        return null;
    }
    /// <summary>
    ///方法2:该类被序列化时,会自动调用
    ///  自定义我们自己的序列化规则
    /// </summary>
    /// <param name="writer">根节点</param>
    public void WriteXml(XmlWriter writer)
    {
        //reader代表的就是根节点(PlayerInfo)
        //如果要自定义序列化规则,一定会用到XmlWriter中的方法来进行序列化
        //1.写节点
        writer.WriteElementString("lv", this.lv.ToString());
        writer.WriteElementString("name", this.name.ToString());

        //2.写节点的子节点
        //  WriteStartElement和WriteEndElement一定是配对出现的
        XmlSerializer s = new XmlSerializer(typeof(int));
        writer.WriteStartElement("lv");
        s.Serialize(writer, lv);
        writer.WriteEndElement();
        XmlSerializer s2 = new XmlSerializer(typeof(string));
        writer.WriteStartElement("name");
        s2.Serialize(writer, name);
        writer.WriteEndElement();

        //3.写属性
        //  参数1 属性名
        //  参数2 属性的值
        //writer.WriteAttributeString("lv", this.lv.ToString());
        //writer.WriteAttributeString("name", "义眼鼎针");
    }
    /// <summary>
    ///方法3:该类被反序列化时,会自动调用
    ///  自定义我们自己的反序列化规则
    /// </summary>
    /// <param name="reader"></param>
    public void ReadXml(XmlReader reader)
    {
        //reader代表的就是根节点(PlayerInfo)
        //1.读节点
        //  读节点方法一:一块一块读
        //  读节点的形式有些奇葩,是一块一块往下读
        //  可用以下代码对比xml文件中的节点来理解
        
        reader.Read();//这是读到了<lv>节点
        reader.Read();//这是读到了<lv>节点包裹的内容
        this.lv = int.Parse(reader.Value);//这是读到<lv>节点的包裹内容的值(12)

        reader.Read();//这是读到了</lv>
        reader.Read();//这是读到了<name>节点
        reader.Read();//这是读到了<name>节点包裹的内容
        this.name = reader.Value;//这是读到<name>节点的包裹内容的值(义眼鼎针)
        //  读节点方法二:循环配合类型判断
        while (reader.Read())
        {
            //  如果类型是Element(节点)
            if (reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    //  PlayerInfo中有两个节点
                    case "lv":
                        reader.Read();
                        this.lv = int.Parse(reader.Value);
                        break;
                    case "name":
                        reader.Read();
                        this.name = reader.Value;
                        break;
                }
            }
        }

        //2.读节点的子节点
        XmlSerializer s = new XmlSerializer(typeof(int));
        XmlSerializer s2 = new XmlSerializer(typeof(string));
        //  跳过根节点
        reader.Read();
        reader.ReadStartElement("lv");
        this.lv = (int)s.Deserialize(reader);
        reader.ReadEndElement();
        reader.ReadStartElement("name");
        this.name = s2.Deserialize(reader).ToString();
        reader.ReadEndElement();

        //3.读属性
        //this.lv = int.Parse(reader["lv"]);
        //this.name = reader["name"];
    }
}
public class Lesson3 : MonoBehaviour
{
    void Start()
    {
        PlayerInfo p = new PlayerInfo();
        p.lv = 12;
        p.name = "义眼鼎针";
        string path = Application.persistentDataPath + "/PlayerInfo.xml";
        //对这个对象将进行序列化
        using (StreamWriter writer = new StreamWriter(path))
        {
            //声明序列化“翻译器”
            XmlSerializer s = new XmlSerializer(typeof(PlayerInfo));
            //传入要写到哪里 和 写谁
            s.Serialize(writer, p);
        }
        //对这个对象将进行反序列化
        using (StreamReader reader = new StreamReader(path))
        {
            //声明反序列化“翻译器”
            XmlSerializer s = new XmlSerializer(typeof(PlayerInfo));
            PlayerInfo p2 = s.Deserialize(reader) as PlayerInfo;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值