我有一个带有主要XElement“详细信息”和几个“详细”XElements的xml文档,对于每个细节元素,我还有几个“节点”元素,这是我的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个属性,对应于“Key”和“value”元素。例如,对于每个细节元素的细节和每个节点元素的详细信息,我想得到3个节点,其中关键元素等于“PRODUCT NO”或“WIRE KIND(CODE)”或“CUT LENGTH”?
这是我的代码,它有效,但我认为它不适合性能:
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问题的一个例子,因为对于每个问题,我必须浏览所有节点,我怎么能用一个循环做同样的事情呢?
答案 0 :(得分:2)
除非您知道性能问题,否则我会在性能之前考虑可读性。但即便如此,你绝对可以改进代码。我会考虑使用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"] });
然后非常可以根据需要添加额外的属性。