You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:15:07