使用linq to xml从XML文档中获取XElements列表的XElements列表

时间:2014-12-02 12:42:29

标签: c# .net xml linq linq-to-xml

我创建了一个节点对象列表:

public class Node
{
    public string Key { get; set; }
    public string Value { get; set; }
}

public class ListNode : List<Node> {  }

我有一个xml文档:

<details>
<detail>
  <node>
    <key>xxx</key>
    <value>111</value>
  </node>
  <node>
    <key>yyy</key>
    <value>222</value>
  </node>
</detail>
<detail>
  <node>
    <key>zzz</key>
    <value>333</value>
  </node>
  <node>
    <key>aaa</key>
    <value>444</value>
  </node>
</detail>
</details>

我想要做的是使用linq到xml将这些xml元素放到ListNode对象列表中:

<node> => Node Object
<detail> => ListNode
<details> => List<ListNode>

这是我对xml请求的linq:

List<ListNode> listNodeDetails = xElement
    .Element("details")
    .Elements("detail")
    .Elements("node")
    .Select(n => new Node() 
        { Key = n.Element("key").Value, 
          Value = n.Element("node").Element("value").Value 
        })
    .ToList();

2 个答案:

答案 0 :(得分:3)

首先,您并不需要NodeListNode类。您应该可以使用KeyValuePair<string,string>(或Tuple<string,string>)和List<KeyValuePari<string,string>>(或List<Tuple<string,string>>)获得相同的结果。以下是List<List<KeyValuePair>>

获取所需结果的方法
var results =
    element.Elements("detail")
            .Select(
                x =>
                    x.Elements("node")
                    .Select(n => new KeyValuePair<string, string>(
                        n.Element("key").Value, 
                        n.Element("value").Value))
                    .ToList())
            .ToList();

这里的技巧是你有一个内部linq语句构建List<KeyValuePair<string,string>>,而外部linq语句构建到List<List<KeyValuePair>>。此外,您必须使用Elements代替Element来获取所有所需元素的收藏。

Node班级(或Tuple<string,string>)中替换是微不足道的。但是在ListNode课程中替换它会更困难,也更不必要。

但是,您现在可以获得List<ListNode>,因为您目前定义了ListNode类。

List<ListNode> list = new List<ListNode>();
foreach (var detail in element.Elements("detail"))
{
    var nodeList = new ListNode();
    nodeList.AddRange(
        detail.Elements("node")
            .Select(
                n => new Node
                {
                    Key = n.Element("key").Value,
                    Value = n.Element("value").Value
                }));
    list.Add(nodeList);
}

在此处,您必须在添加节点之前创建ListNode,而不是使用ToList扩展方法。您可以将foreach转换为linq表达式,但我通常会尽可能避免使用多个语句的lambda。

答案 1 :(得分:1)

你并没有真正说过你被困在哪里......无论如何,这应该可以解决问题。

var xdoc = XDocument.Load("Test.xml");

var listNodeDetails = xdoc.Root
    .Elements("detail")
    .Elements("node").Select(
        n => new Node
        {
            Key = n.Element("key").Value,
            Value = n.Element("value").Value
        }).ToList();