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

Posted

技术标签:

【中文标题】有没有聪明的方法来解析 xml 到列表?【英文标题】:Is there smart way to parse xml to list? 【发布时间】:2021-11-17 12:28:50 【问题描述】:

有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 个 obj 的 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&lt;MyObject&gt;,但我不想逐个节点地解析它。有什么聪明的方法吗?

更新

在这里,我得到了什么:Empty list

【问题讨论】:

你能解释一下“列表中的所有对象都将成为可反序列化 xml 的第一个对象”的意思吗? 需要以一种或另一种方式反序列化它 请提供有效的 XML 和有效的 C# 类。你知道,可以编译的东西和可以被 XML 解析器读取的 XML。这将使我们更容易理解您的问题并为您提供数量级的帮助。 ^^ 或者换一种说法:请提供minimal reproducible example 我已更改示例以尝试对应于最小可重现示例。 【参考方案1】:

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

[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

如果需要处理

+Inffloat.PositiveInfinity -Inffloat.NegativeInfinity

那么您需要更改&lt;doubleProp&gt; 的文本。一种方法如下:

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);

【讨论】:

这不起作用。这是链接,它说的地方。而且我也尝试过这样做。没有错误,但列表为空。 docs.microsoft.com/en-us/dotnet/api/… @ddg 反序列化xml没有任何问题,请看我关于监视窗口的截图。在您的情况下,哪个列表是空的? @(Peter Csala) 我添加了截图。由于某种原因,我的清单是空的。 @ddg 在您的共享图像中,PgnCount"671"。在您的问题中,与PgnCount"671" 没有任何关系。请根据您发布的 xml 评估我提出的解决方案。 @ddg 请记住,xml 反序列化区分大小写。这意味着如果您有一个名为 myobject 的 xml 节点,那么相关的 ElementName 必须相同。如果您提供了其他任何内容(例如 myObjectmyobjectsMyObject),那么脱轨器将无法使用相关的 xml 数据填充该属性。

以上是关于有没有聪明的方法来解析 xml 到列表?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL 将 XML 结构转置/展平到列

以编程方式读取 ildasm 输出的最佳方法是啥

双向将字符串的“虚拟”列表绑定到列

将解析的 html 存储为 XML 输出的最佳方法

怎么解决 ? (将列表添加到列数据框pyspark)

scratch聪明的小猫 电子学会图形化编程scratch等级考试四级真题和答案解析2021-12