当前位置: 首页 > news >正文

Unity_数据持久化_IXmlSerializable接口

Unity数据持久化

三、XML数据持久化

3.5 IXmlSerializable接口

3.5.1 IXmlSerializable接口基础概念

什么是IXmlSerializable接口:
IXmlSerializable 是.NET框架提供的一个接口,允许类自定义XML序列化和反序列化的过程。当默认的XML序列化行为无法满足需求时,可以实现这个接口来完全控制XML的读写过程。

接口定义:

public interface IXmlSerializable
{XmlSchema GetSchema();void ReadXml(XmlReader reader);void WriteXml(XmlWriter writer);
}

核心方法说明:

  • GetSchema():返回XML架构定义,通常返回null
  • ReadXml(XmlReader reader):自定义XML反序列化过程
  • WriteXml(XmlWriter writer):自定义XML序列化过程
3.5.2 实现IXmlSerializable接口

基本实现结构:

using System.Xml.Serialization;
using System.Xml;
using System.Xml.Schema;public class TextData : IXmlSerializable
{public string text = "gsffs";public int age;public List<string> list;public int[] array = new int[3] { 1, 2, 3 };// 实现IXmlSerializable接口public XmlSchema GetSchema(){return null; // 通常返回null}public void ReadXml(XmlReader reader){// 自定义反序列化逻辑}public void WriteXml(XmlWriter writer){// 自定义序列化逻辑}
}
3.5.3 自定义XML序列化(WriteXml方法)

WriteXml方法用于控制对象如何序列化为XML格式。有三种主要的写入方式:

1. 写入属性(Attribute)

public void WriteXml(XmlWriter writer)
{// 将数据作为XML元素的属性写入writer.WriteAttributeString("text", text);writer.WriteAttributeString("age", age.ToString());
}

生成的XML格式:

<TextData text="gsffs" age="25" />

2. 写入元素节点(Element)

public void WriteXml(XmlWriter writer)
{// 将数据作为独立的XML元素写入writer.WriteElementString("text", text);writer.WriteElementString("age", age.ToString());
}

生成的XML格式:

<TextData><text>gsffs</text><age>25</age>
</TextData>

3. 写入包裹节点(复杂序列化)

public void WriteXml(XmlWriter writer)
{// 使用XmlSerializer进行复杂类型的序列化XmlSerializer ser = new XmlSerializer(typeof(string));// 写入text字段writer.WriteStartElement("text1");ser.Serialize(writer, text);writer.WriteEndElement();// 写入age字段XmlSerializer ser2 = new XmlSerializer(typeof(int));writer.WriteStartElement("age");ser2.Serialize(writer, age);writer.WriteEndElement();
}

生成的XML格式:

<TextData><text1>gsffs</text1><age>25</age>
</TextData>
3.5.4 自定义XML反序列化(ReadXml方法)

ReadXml方法用于控制如何从XML格式反序列化为对象。有三种主要的读取方式:

1. 读取属性(Attribute)

public void ReadXml(XmlReader reader)
{// 从XML元素的属性中读取数据age = int.Parse(reader.GetAttribute("age"));text = reader.GetAttribute("text");
}

2. 读取元素节点(Element)

public void ReadXml(XmlReader reader)
{// 方法1:手动控制读取过程reader.Read(); // 读取text节点reader.Read(); // 读取text包裹内容text = reader.Value;reader.Read(); // 读取text末节点reader.Read(); // 读取age节点reader.Read(); // 读取age包裹内容age = int.Parse(reader.Value);reader.Read(); // 读取age末节点
}

3. 使用循环读取多个元素

public void ReadXml(XmlReader reader)
{// 方法2:使用循环遍历所有元素while (reader.Read()){if (reader.NodeType == XmlNodeType.Element){switch (reader.Name){case "text":reader.Read();text = reader.Value;break;case "age":reader.Read();age = int.Parse(reader.Value);break;}}}
}

4. 读取包裹节点(复杂反序列化)

public void ReadXml(XmlReader reader)
{// 使用XmlSerializer进行复杂类型的反序列化XmlSerializer ser3 = new XmlSerializer(typeof(string));XmlSerializer ser4 = new XmlSerializer(typeof(int));reader.Read(); // 跳过根节点reader.ReadStartElement();text = (string)ser3.Deserialize(reader);reader.ReadEndElement();reader.Read();reader.ReadStartElement();age = (int)ser4.Deserialize(reader);reader.ReadEndElement();
}
3.5.5 完整的IXmlSerializable实现示例

基于您的代码的完整实现:

using UnityEngine;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Collections.Generic;/// <summary>
/// 自定义XML序列化的数据类
/// 实现IXmlSerializable接口以完全控制XML读写过程
/// </summary>
public class TextData : IXmlSerializable
{public string text = "gsffs";public int age;public List<string> list;public int[] array = new int[3] { 1, 2, 3 };/// <summary>/// 返回XML架构定义/// </summary>/// <returns>通常返回null</returns>public XmlSchema GetSchema(){return null;}/// <summary>/// 自定义XML反序列化过程/// </summary>/// <param name="reader">XML读取器</param>public void ReadXml(XmlReader reader){// 使用XmlSerializer进行复杂类型的反序列化XmlSerializer ser3 = new XmlSerializer(typeof(string));XmlSerializer ser4 = new XmlSerializer(typeof(int));reader.Read(); // 跳过根节点reader.ReadStartElement();text = (string)ser3.Deserialize(reader);reader.ReadEndElement();reader.Read();reader.ReadStartElement();age = (int)ser4.Deserialize(reader);reader.ReadEndElement();}/// <summary>/// 自定义XML序列化过程/// </summary>/// <param name="writer">XML写入器</param>public void WriteXml(XmlWriter writer){// 使用XmlSerializer进行复杂类型的序列化XmlSerializer ser = new XmlSerializer(typeof(string));writer.WriteStartElement("text1");ser.Serialize(writer, text);writer.WriteEndElement();XmlSerializer ser2 = new XmlSerializer(typeof(int));writer.WriteStartElement("age");ser2.Serialize(writer, age);writer.WriteEndElement();}
}/// <summary>
/// IXmlSerializable接口测试类
/// 演示如何使用自定义XML序列化
/// </summary>
public class XmlSerilizef : MonoBehaviour
{void Start(){// 设置存储路径string path = Application.persistentDataPath + "/TextData.xml";print("存储路径: " + path);// 创建测试数据TextData textData = new TextData();textData.list = new List<string>() { "1", "2", "3" };textData.age = 25;// 序列化对象到XML文件XmlSerializer ser444 = new XmlSerializer(typeof(TextData));using (StreamWriter sw = new StreamWriter(path)){ser444.Serialize(sw, textData);}// 从XML文件反序列化对象TextData textData2;using (StreamReader sr = new StreamReader(path)){textData2 = (TextData)ser444.Deserialize(sr);}// 验证反序列化结果if (textData2 != null){print("反序列化成功!");print("文本: " + textData2.text);print("年龄: " + textData2.age);}}
}
3.5.6 IXmlSerializable接口的优势和应用场景

优势:

  1. 完全控制:可以完全控制XML的读写过程
  2. 灵活性:支持复杂的XML结构和自定义格式
  3. 性能优化:可以针对特定需求优化序列化性能
  4. 兼容性:可以处理不同版本的XML格式

应用场景:

  1. 复杂数据结构:当默认序列化无法处理复杂的数据结构时
  2. 自定义格式:需要生成特定格式的XML时
  3. 性能要求:对序列化性能有特殊要求时
  4. 版本兼容:需要处理不同版本的XML格式时
3.5.7 注意事项和最佳实践

1. 实现要求

// 必须实现所有三个方法
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) { /* 自定义读取逻辑 */ }
public void WriteXml(XmlWriter writer) { /* 自定义写入逻辑 */ }

2. 错误处理

public void ReadXml(XmlReader reader)
{try{// 自定义读取逻辑reader.Read();text = reader.Value;}catch (System.Exception e){Debug.LogError("XML读取失败: " + e.Message);}
}

通过实现 IXmlSerializable 接口,可以为Unity项目提供高度自定义的XML序列化解决方案,特别适合需要精确控制XML格式的复杂应用场景。

http://www.lryc.cn/news/609197.html

相关文章:

  • 【视频内容创作】PR的关键帧动画
  • SQL157 更新记录(一)
  • linux下jvm之jstack的使用
  • 代码随想录day53图论4
  • Java 大视界 -- Java 大数据在智能教育学习资源个性化推荐与学习路径动态调整中的深度应用(378)
  • 【LLM】 BaseModel的作用
  • 【0基础PS】PS工具详解--文字工具
  • Shell脚本-变量是什么
  • 思途JSP学习 0802(项目完整流程)
  • Linux网络编程 --- 多路转接select
  • Unity JobSystem 与 BurstCompiler 资料
  • 2025.8.3
  • webrtv弱网-QualityScalerResource 源码分析及算法原理
  • 【大模型实战】向量数据库实战 - Chroma Milvus
  • Linux mount挂载选项详解(重点关注nosuid)
  • ESP32开发问题汇总
  • ZStack Cloud 5.3.40正式发布
  • 第15届蓝桥杯Scratch图形化国赛初/中级组2024年9月7日真题
  • Product Hunt 每日热榜 | 2025-08-02
  • 01数据结构-时间复杂度和空间复杂度
  • Petalinux 23.2 构建过程中常见下载错误及解决方法总结
  • ORA-12514:TNS: 监听程序当前无法识别连接描述符中请求的服务
  • 小白学OpenCV系列2-理解图像
  • 使用纯Docker命令搭建多服务环境(Linux版)
  • Web 开发 11
  • 腾讯人脸识别
  • lumerical——锥形波导偏振转换
  • 大白话讲解MCP
  • 机器学习第四课之决策树
  • Android 之 蓝牙通信(2.0 经典)