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

如何在C#中将XML中item0-itemNN反序列化为数组/列表?

解决XML中带数字后缀的元素反序列化为列表的问题

针对你遇到的这个XML反序列化问题——把item0到itemNN这类带数字后缀的元素映射到data类的列表属性里,我有两种实用的解决方案,你可以根据自己的需求选择:

方案一:使用[XmlAnyElement]手动处理元素(推荐,无需额外事件绑定)

这种方法通过在类中添加一个用于XML序列化的中间属性,把所有未被映射的元素捕获后转换为你的item对象,同时对外暴露一个干净的Items列表供业务代码使用:

public class data {
    private List<item> _items = new List<item>();

    // 用于XML序列化/反序列化的中间属性,捕获所有未匹配的元素
    [XmlAnyElement]
    public XmlElement[] ItemsXml {
        get {
            // 序列化时:把Items列表转换为带数字后缀的XML元素
            var doc = new XmlDocument();
            return _items.Select((item, index) => {
                var elem = doc.CreateElement($"item{index}");
                elem.SetAttribute("attr1", item.attr1);
                elem.SetAttribute("attr2", item.attr2);
                elem.SetAttribute("attr3", item.attr3.ToString());
                elem.SetAttribute("attr4", item.attr4.ToString());
                return elem;
            }).ToArray();
        }
        set {
            // 反序列化时:把捕获的XML元素转换为item对象,添加到列表
            _items.Clear();
            if (value == null) return;
            foreach (var elem in value) {
                // 只处理以"item"开头的元素
                if (elem.Name.StartsWith("item", StringComparison.Ordinal)) {
                    var newItem = new item {
                        attr1 = elem.GetAttribute("attr1"),
                        attr2 = elem.GetAttribute("attr2"),
                        attr3 = bool.Parse(elem.GetAttribute("attr3")),
                        attr4 = double.Parse(elem.GetAttribute("attr4"))
                    };
                    _items.Add(newItem);
                }
            }
        }
    }

    // 供业务代码使用的忽略XML的列表属性
    [XmlIgnore]
    public List<item> Items {
        get => _items;
        set => _items = value ?? new List<item>();
    }

    [XmlAttribute("timestamp")]
    public int timestamp;
}

public class item {
    [XmlAttribute("attr1")]
    public string attr1 { get; set; }
    [XmlAttribute("attr2")]
    public string attr2 { get; set; }
    [XmlAttribute("attr3")]
    public bool attr3 { get; set; }
    [XmlAttribute("attr4")]
    public double attr4 { get; set; }
}

方案二:利用XmlSerializer的UnknownElement事件处理

如果你不想修改类的结构,可以在反序列化的时候绑定UnknownElement事件,捕获所有未被映射的item*元素并手动添加到列表中:

// 首先保持你的类结构(修正原来的错误属性)
public class data {
    // 这里不需要错误的[XmlElement("itemNN?")],用XmlIgnore暂时忽略,通过事件填充
    [XmlIgnore]
    public List<item> Items { get; set; } = new List<item>();
    
    [XmlAttribute("timestamp")]
    public int timestamp;
}

public class item {
    [XmlAttribute("attr1")]
    public string attr1 { get; set; }
    [XmlAttribute("attr2")]
    public string attr2 { get; set; }
    [XmlAttribute("attr3")]
    public bool attr3 { get; set; }
    [XmlAttribute("attr4")]
    public double attr4 { get; set; }
}

// 反序列化时的处理代码
var serializer = new XmlSerializer(typeof(data));
// 绑定未知元素处理事件
serializer.UnknownElement += (sender, e) => {
    var currentData = (data)e.ObjectBeingDeserialized;
    // 判断元素是否是我们需要的item*
    if (e.Element.Name.StartsWith("item", StringComparison.Ordinal)) {
        var newItem = new item {
            attr1 = e.Element.GetAttribute("attr1"),
            attr2 = e.Element.GetAttribute("attr2"),
            attr3 = bool.Parse(e.Element.GetAttribute("attr3")),
            attr4 = double.Parse(e.Element.GetAttribute("attr4"))
        };
        currentData.Items.Add(newItem);
    }
};

// 执行反序列化
using (var reader = new StringReader(yourXmlContent)) {
    var result = (data)serializer.Deserialize(reader);
    // 此时result.Items已经包含了所有item0到itemNN的对象
}

注意事项

  • 两种方案都能处理任意数量的item*元素,不管后缀数字是多少
  • 如果你的XML中还有其他类似命名的元素(比如otherItem0),可以调整判断条件(比如用正则匹配^item\d+$)来更精准地筛选目标元素
  • 方案一的优势是序列化和反序列化都能自动处理,方案二更适合临时的反序列化场景

内容的提问来源于stack exchange,提问作者raiserle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:19:59