C#如何将名称不同但结构相同的XML元素反序列化归入同一个类?
方案1:实现IXmlSerializable自定义反序列化逻辑
这种方式可以直接兼容默认的XmlSerializer调用方式,不需要额外预处理XML:
using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; [XmlRoot("programs")] public class Programs : IXmlSerializable { public List<Item> Items { get; set; } = new List<Item>(); public XmlSchema GetSchema() => null; public void ReadXml(XmlReader reader) { reader.ReadStartElement("programs"); var itemSerializer = new XmlSerializer(typeof(Item)); while (reader.NodeType == XmlNodeType.Element) { // 匹配所有以item开头的节点,也可以加正则判断是否为item+数字格式,避免误匹配 if (reader.Name.StartsWith("item")) { var item = (Item)itemSerializer.Deserialize(reader); Items.Add(item); } else { reader.Skip(); } } reader.ReadEndElement(); } // 如果不需要序列化回XML,这个方法可以空实现 public void WriteXml(XmlWriter writer) { for (int i = 0; i < Items.Count; i++) { writer.WriteStartElement($"item{i}"); var serializer = new XmlSerializer(typeof(Item)); serializer.Serialize(writer, Items[i], new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty })); writer.WriteEndElement(); } } } public class Item { public object prop1 { get; set; } public object prop2 { get; set; } public object prop3 { get; set; } }
调用方式和普通反序列化完全一致:
var serializer = new XmlSerializer(typeof(Programs)); using var reader = new StreamReader("你的xml文件路径"); var programs = (Programs)serializer.Deserialize(reader); // 直接通过programs.Items访问所有item集合
方案2:先读取XML节点再逐个反序列化
如果不想修改Programs类的结构,也可以用XDocument预处理XML,直接提取所有目标节点反序列化,甚至不需要定义Programs类:
using System.Xml.Linq; using System.Xml.Serialization; var xDoc = XDocument.Load("你的xml文件路径"); var items = xDoc.Root.Elements() .Where(e => e.Name.LocalName.StartsWith("item")) .Select(e => { using var reader = e.CreateReader(); var serializer = new XmlSerializer(typeof(Item)); return (Item)serializer.Deserialize(reader); }) .ToList();
两种方案都可以完全避免定义200个ItemN类和对应的属性,即使后续item的序号超过200也能自动适配,不需要修改代码。如果担心匹配到非目标的item开头节点,可以把判断条件替换为正则匹配^item\d+$即可。
内容的提问来源于stack exchange,提问作者Baptiste Rieber
相关产品推荐
相关产品推荐

