C# 如何实现自定义的xml序列化逻辑

来源:这里教程网 时间:2026-02-21 17:31:43 作者:

在 C# 中,如果需要实现自定义的 XML 序列化逻辑,可以通过实现 IXmlSerializable 接口来完全控制对象如何被序列化和反序列化为 XML。这种方式适用于标准的 XmlSerializer,允许你自定义字段映射、处理特殊数据格式或兼容已有 XML 结构。

实现 IXmlSerializable 接口

一个类要支持自定义 XML 序列化,需实现 IXmlSerializable 接口,该接口包含三个成员:

ReadXml(XmlReader reader):从 XmlReader 中读取数据并还原对象状态 WriteXml(XmlWriter writer):将对象数据写入 XmlWriter GetSchema():通常返回 null,因为一般不需要 XSD 支持

注意:必须提供无参构造函数,否则 XmlSerializer 反序列化时会失败。

示例:自定义序列化 Person 类

假设有一个 Person 类,希望将其序列化为如下格式:

<Person>
  <Name>Alice</Name>
  <Age>30</Age>
</Person>

但内部字段命名不同,且想控制输出顺序和格式:

using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
public class Person : IXmlSerializable
{
    public string FullName { get; set; }
    public int YearsOld { get; set; }
    // 必须提供无参构造函数
    public Person() { }
    public Person(string name, int age)
    {
        FullName = name;
        YearsOld = age;
    }
    public XmlSchema GetSchema() => null;
    public void ReadXml(XmlReader reader)
    {
        // 读取开始标签 <Person>
        reader.ReadStartElement("Person");
        // 读取子元素
        FullName = reader.ReadElementString("Name");
        YearsOld = int.Parse(reader.ReadElementString("Age"));
        // 读取结束标签
        reader.ReadEndElement();
    }
    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Name", FullName);
        writer.WriteElementString("Age", YearsOld.ToString());
    }
}

使用自定义序列化类

序列化和反序列化的用法与普通类一致:

using System.IO;
using System.Xml.Serialization;
// 序列化
var person = new Person("Bob", 25);
var serializer = new XmlSerializer(typeof(Person));
using (var writer = new StringWriter())
{
    serializer.Serialize(writer, person);
    Console.WriteLine(writer.ToString());
    // 输出包含 <Name> 和 <Age> 的 XML
}
// 反序列化
using (var reader = new StringReader(xmlString))
{
    var restored = (Person)serializer.Deserialize(reader);
    Console.WriteLine($"{restored.FullName}, {restored.YearsOld}");
}

高级场景与注意事项

在更复杂的场景中,可能需要处理嵌套对象、集合、属性、命名空间或条件输出:

WriteXml 中可手动写入属性:
writer.WriteAttributeString("id", Id.ToString())
ReadXml 中可用
reader.MoveToAttribute("attr")
读取属性
避免调用
reader.Read()
过度,防止解析错位
对于复杂结构,建议先调用
reader.ReadStartElement()
,再逐项处理,最后
ReadEndElement()
若字段可为空,注意判断
reader.IsStartElement()

基本上就这些。通过实现 IXmlSerializable,你可以精确控制 XML 的生成与解析过程,适合对接遗留系统或特定协议。虽然比用 DataContract 或自动特性复杂,但灵活性更高。不复杂但容易忽略无参构造和读写平衡。

相关推荐

热文推荐