实现IXmlSerializable接口可自定义XML序列化逻辑,需提供无参构造函数并实现ReadXml、WriteXml和GetSchema方法,适用于控制字段映射与兼容特定XML结构。

在 C# 中,如果需要实现自定义的 XML 序列化逻辑,可以通过实现 IXmlSerializable 接口来完全控制对象如何被序列化和反序列化为 XML。这种方式适用于标准的 XmlSerializer,允许你自定义字段映射、处理特殊数据格式或兼容已有 XML 结构。
实现 IXmlSerializable 接口
一个类要支持自定义 XML 序列化,需实现 IXmlSerializable 接口,该接口包含三个成员:
- ReadXml(XmlReader reader):从 XmlReader 中读取数据并还原对象状态
- WriteXml(XmlWriter writer):将对象数据写入 XmlWriter
- GetSchema():通常返回 null,因为一般不需要 XSD 支持
red">注意:必须提供无参构造函数,否则 XmlSerializer 反序列化时会失败。
示例:自定义序列化 Person 类
假设有一个 Person 类,希望将其序列化为如下格式:
Alice 30
但内部字段命名不同,且想控制输出顺序和格式:
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)
{
// 读取开始标签 zuojiankuohaophpcnPersonyoujiankuohaophpcn
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());
// 输出包含 zuojiankuohaophpcnNameyoujiankuohaophpcn 和 zuojiankuohaophpcnAgeyoujiankuohaophpcn 的 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 或自动特性复杂,但灵活性更高。不复杂但容易忽略无参构造和读写平衡。










