有没有聪明的方法来解析 xml 列表?

Is there smart way to parse xml to list?

有 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,所以我的结果列表将包含第 0 个对象的 ObjCount。

我已经创建了 类 -- 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>,但我不想逐个节点地解析它。有什么聪明的方法吗?

更新

在这里,我得到的是:Empty list

如果您像这样注释数据模型:

[XmlRoot(ElementName = "myobjectlist")]
public class MyObjectList
{
    [XmlAttribute(AttributeName = "objectCount")]
    public string ObjectCount { get; set; }

    [XmlElement(ElementName = "myobject")]
    public List<MyObject> MyObjects { get; set; }
}
[XmlRoot(ElementName = "myobject")]
public class MyObject
{
    [XmlAttribute]
    public string Number { get; set; }
    [XmlAttribute]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "MyChildObectsCount")]
    public string MyChildObjectsCount { get; set; }

    [XmlElement(ElementName = "intProp")]
    public string IntProp { get; set; }
    [XmlElement(ElementName = "stringProp")]
    public string StringProp { get; set; }
    [XmlElement(ElementName = "doubleProp")]
    public string DoubleProp { get; set; }
    [XmlElement(ElementName = "MyChildObj")]
    public List<MyChildObject> MyChildObjects { get; set; }
}
[XmlRoot(ElementName = "MyChildObj")]
public class MyChildObject
{
    [XmlAttribute]
    public string Number { get; set; }
    [XmlAttribute]
    public string Name { get; set; }

    [XmlElement(ElementName = "childIntProp")]
    public string ChildIntProp { get; set; }
    [XmlElement(ElementName = "childStringProp")]
    public string ChildStringProp { get; set; }
}

反序列化逻辑很简单:

StreamReader reader = new StreamReader(File.OpenRead("sample.xml"));
var serializer = new XmlSerializer(typeof(MyObjectList));
var data = (MyObjectList)serializer.Deserialize(reader);

更新 #1


更新 #2

如需办理

  • +Inf 作为 float.PositiveInfinity
  • -Inf 作为 float.NegativeInfinity

然后您需要更改 <doubleProp> 的文本。一种方法如下:

var malformedXml = File.ReadAllText("sample.xml");
var fixedXml = malformedXml
    .Replace("<doubleProp>+Inf</doubleProp>", "<doubleProp>Infinity</doubleProp>")
    .Replace("<doubleProp>-Inf</doubleProp>", "<doubleProp>-Infinity</doubleProp>");

var fixedXmlStream = new MemoryStream();
var writer = new StreamWriter(fixedXmlStream);
writer.Write(fixedXml);
writer.Flush();
fixedXmlStream.Position = 0;
var reader = new StreamReader(fixedXmlStream);