选择一些特定的 XML 元素以列出匿名对象
本文关键字:对象 元素 XML 选择 | 更新日期: 2023-09-27 18:34:13
我有一个xml文档,其中包含主要的XElement"详细信息"和几个"详细信息"XElements,对于每个详细信息元素,我还有几个"节点"元素,这是我xml文档的一部分:
<details>
<detail>
<node>
<key>HEADER ID</key>
<value>D10</value>
</node>
<node>
<key>PRODUCT NO</key>
<value>9671834480D04 </value>
</node>
<node>
<key>WIRE (CODE)</key>
<value>AD8</value>
</node>
<node>
<key>WIRE SIZE(CODE)</key>
<value>047</value>
</node>
<node>
<key>WIRE COLOR(CODE)</key>
<value>30</value>
</node>
<node>
<key>CUT LENGTH</key>
<value>01910</value>
</node>
</detail>
<detail>
<node>
...
</node>
...
</detail>
...
<details>
我正在尝试将此 xml 部分转换为仅包含 3 个属性的对象列表,这些属性对应于"键"和"值"元素。 例如,对于每个细节元素的详细信息和每个节点元素的详细信息,我只想得到 3 个节点,其中关键元素等于"产品编号"或"电线种类(代码)"或"切割长度"?
这是我的代码,它可以工作,但我认为它不适合性能:
var champs =
from detail in details
let productNo = detail.Elements("node")
.Where(k => k.Element("key")
.Value == "PRODUCT NO")
.Select(v => v.Element("value").Value)
.First()
let wireCode = detail.Elements("node")
.Where(k => k.Element("key").Value == "WIRE (CODE)")
.Select(v => v.Element("value").Value)
.First()
let cutLength = detail.Elements("node")
.Where(k => k.Element("key").Value == "CUT LENGTH")
.Select(v => v.Element("value").Value)
.First()
select new { ProductNo = productNo, WireCode = wireCode , CutLength = cutLength };
我认为这是选择 N+1 问题的一个例子,因为对于每个属性,我必须浏览所有节点,我怎样才能用一个循环做同样的事情?
我实际上会在性能之前考虑可读性,除非您知道自己有性能问题。但即便如此,您绝对可以改进代码。我会考虑使用 ToDictionary
将每个detail
元素转换为Dictionary<string, string>
,然后您可以获得所需的位:
var query = details.Select(d => d.Elements("node")
.ToDictionary(n => n.Element("key").Value,
n => n.Element("value").Value))
.Select(x => new { ProductNo = x["PRODUCT NO"],
WireCode = x["WIRE (CODE)"],
CutLength = x["CUT LENGTH"] });
然后,您可以根据需要轻松添加额外的属性。