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

如何智能将指定结构XML解析为List<MyObject>,无需逐节点解析?

问题

我有如下结构的XML文件:

<?xml version="1.0"?>
<myobjectlist objectCount = "3">
    <myobject Number = "0" Name="My First Object" MyChildObectsCount = "2">
        <intProp>5</intProp>
        <stringProp>Str1</stringProp>
        <doubleProp>35.1</doubleProp>
        <MyChildObj Number = "100" Name = "My first child object">
            <childIntProp>1</childIntProp>
            <childStringProp>CStr1</childStringProp>
        </MyChildObj>
        <MyChildObj Number = "120" Name = "My child object">
            <childIntProp>15</childIntProp>
            <childStringProp>CStr2</childStringProp>
        </MyChildObj>
    </myobject>
    <myobject Number = "145" Name="My second Object" MyChildObectsCount = "1">
        <intProp>96</intProp>
        <stringProp>Str2</stringProp>
        <doubleProp>+Inf</doubleProp>
        <MyChildObj Number = "250" Name = "This's child object">
            <childIntProp>62</childIntProp>
            <childStringProp>CStr3</childStringProp>
        </MyChildObj>
    </myobject>
    <myobject Number = "261" Name="My last Object" MyChildObectsCount = "3">
        <intProp>9</intProp>
        <stringProp>Str45</stringProp>
        <doubleProp>1.6449635e+07</doubleProp>
        <MyChildObj Number = "150" Name = "Almost last child object">
            <childIntProp>-1</childIntProp>
            <childStringProp>CStr41</childStringProp>
        </MyChildObj>
        <MyChildObj Number = "680" Name = "Prelast child object">
            <childIntProp>72</childIntProp>
            <childStringProp>CStr42</childStringProp>
        </MyChildObj>
        <MyChildObj Number = "127" Name = "Last child object">
            <childIntProp>64</childIntProp>
            <childStringProp>CStr222</childStringProp>
        </MyChildObj>
    </myobject>
</myobjectlist>

我曾尝试使用XMLSerializer进行反序列化,但发现它无法正确反序列化为列表,得到的结果列表中所有对象都是XML的第一个对象,列表元素总数等于XML内对象总数,后续操作还出现了返回空列表的问题。
我已经创建了对应XML对象的实体类,代码如下:

public class MyObject{
    int Number;
    string Name;
    int IntProp;
    string stringProp;
    double doubleProp;
    List<MyChildObject> myChildObjects;
}

public class MyChildObject{
    int Number;
    string Name;
    int childIntProp;
    string childStringProp;
}

我需要从该XML文件中获取List<MyObject>类型的结果,且不想逐节点手动解析,请问有什么智能的实现方法?

更新说明

当前我执行操作得到的结果为空列表。


解决方案

你遇到的问题本质是XmlSerializer的映射规则不匹配,核心问题有两个:一是你的实体类成员都是私有字段,序列化器没有访问权限;二是没有显式配置XML节点和实体类的映射关系,导致名称不匹配时无法正确赋值。
按以下步骤修改即可直接反序列化得到目标结果:

步骤1:修正实体类,添加映射特性

using System.Collections.Generic;
using System.Xml.Serialization;

// 映射XML根节点myobjectlist
[XmlRoot("myobjectlist")]
public class MyObjectListRoot
{
    [XmlAttribute("objectCount")]
    public int ObjectCount { get; set; }

    // 直接映射根节点下所有名为myobject的子节点到集合
    [XmlElement("myobject")]
    public List<MyObject> MyObjects { get; set; }
}

public class MyObject
{
    [XmlAttribute("Number")]
    public int Number { get; set; }

    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlAttribute("MyChildObectsCount")]
    public int MyChildObjectsCount { get; set; }

    [XmlElement("intProp")]
    public int IntProp { get; set; }

    [XmlElement("stringProp")]
    public string StringProp { get; set; }

    [XmlElement("doubleProp")]
    public double DoubleProp { get; set; }

    // 映射当前节点下所有名为MyChildObj的子节点到集合
    [XmlElement("MyChildObj")]
    public List<MyChildObject> MyChildObjects { get; set; }
}

public class MyChildObject
{
    [XmlAttribute("Number")]
    public int Number { get; set; }

    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlElement("childIntProp")]
    public int ChildIntProp { get; set; }

    [XmlElement("childStringProp")]
    public string ChildStringProp { get; set; }
}

步骤2:编写反序列化逻辑

using System.IO;
using System.Xml.Serialization;

public List<MyObject> GetMyObjectsFromXml(string xmlFilePath)
{
    var serializer = new XmlSerializer(typeof(MyObjectListRoot));
    using (var streamReader = new StreamReader(xmlFilePath))
    {
        var root = (MyObjectListRoot)serializer.Deserialize(streamReader);
        return root.MyObjects;
    }
}

注意事项

  • 所有需要反序列化的成员必须声明为public的属性,且同时包含get和set方法,私有字段无法被XmlSerializer赋值
  • 用[XmlAttribute]标记对应XML节点属性的属性,用[XmlElement]标记对应XML子元素的属性,避免大小写、命名差异导致的映射失败
  • 如果集合的子节点没有额外的父容器包裹,直接给集合属性加[XmlElement("子节点名")]即可,不需要额外定义容器类

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:15:03