有没有聪明的方法来解析 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<MyObject>
,但我不想逐个节点地解析它。有什么聪明的方法吗?
更新
在这里,我得到了什么: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
如果需要处理
+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);
【讨论】:
这不起作用。这是链接,它说的地方。而且我也尝试过这样做。没有错误,但列表为空。 docs.microsoft.com/en-us/dotnet/api/… @ddg 反序列化xml没有任何问题,请看我关于监视窗口的截图。在您的情况下,哪个列表是空的? @(Peter Csala) 我添加了截图。由于某种原因,我的清单是空的。 @ddg 在您的共享图像中,PgnCount
是 "671"
。在您的问题中,与PgnCount
和"671"
没有任何关系。请根据您发布的 xml 评估我提出的解决方案。
@ddg 请记住,xml 反序列化区分大小写。这意味着如果您有一个名为 myobject
的 xml 节点,那么相关的 ElementName
必须相同。如果您提供了其他任何内容(例如 myObject
、myobjects
、MyObject
),那么脱轨器将无法使用相关的 xml 数据填充该属性。以上是关于有没有聪明的方法来解析 xml 到列表?的主要内容,如果未能解决你的问题,请参考以下文章