LINQ选择特定元素

时间:2014-07-31 14:41:57

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

基本上,我在试图了解我在哪里出错时遇到了麻烦..

基本上,我有以下XML:

<Directory>
  <CustDirectory name="Name1">
  <Person name="Foo" />
  <Person name="Goo" />
  <Person name="Gentu" />
  </CustDirectory>

  <CustDirectory name="Name2">
  <Person name="F22" />
  <Person name="Gentu" />
  </CustDirectory>
</Directory>

使用表单,我正在更新联系人列表,我想根据哪个类别(存储为字符串)将列表写入XML。

因此我决定使用LINQ来做这件事,但是,我似乎无法找到.Where并且已经阅读了有关stackoverflow的问题并且似乎无法弄明白。

这是我的尝试:

var con = e.Element("Directory").Element("CustDirectory").Descendants("Person").Where(p => p.Attribute("name").Value.ToStr == "Name2");

这不起作用并抛出一个空异常......当我取消.Where子句时,后代中包含的数据显示正确。

有没有人可以告诉我LINQ查询在哪里出错了所以我可以选择特定根的所有后代?

4 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,那么您正在尝试提取属于给定CustDirectory的所有Person元素。在这种情况下,您应该使用更像:

var con = e.Element("Directory").Descendants("CustDirectory").Where(p => p.Attribute("name").Value == "Name2").Elements("Person");

答案 1 :(得分:1)

ToStr部分外,一切看起来都很正确。

要仅选择名称为Person的{​​{1}}下的CustDirectory元素,您需要将Name2放在其上,如下所示:

Where

请注意,我将var con = e.Element("Directory").Elements("CustDirectory") .First(cd => cd.Attribute("name").Value == "Name2").Descendants("Person"); 更改为Element("CustDirectory")

答案 2 :(得分:1)

您一开始不需要Element("Directory"),因为e自我已经被引用<Directory>(如果eXDocument而不是XElement你在评论中说的<Person>。此示例能够返回var e = XElement.Parse("..."); var con = e.Elements("CustDirectory") .Where(p => p.Attribute("name").Value == "Name2") .Elements("Person"); 个节点,提供有问题的样本XML:

{{1}}

答案 3 :(得分:1)

void Main()
{
    var xml  = @"<Directory>
    <CustDirectory name=""Name1"">
    <Person name=""Foo""/>
    <Person name=""Goo""/>
    <Person name=""Gentu""/>
    </CustDirectory>
    <CustDirectory name=""Name2"">
    <Person name=""F22""/>
    <Person name=""Gentu""/>
    </CustDirectory>
    </Directory>";
    var xmlDoc = XDocument.Parse(xml);
    var con = xmlDoc.Element("Directory")
                    .Elements("CustDirectory")
                    .Where(p => p.Attribute("name").Value == "Name2")
                    .Descendants("Person")
//  added bonus to get a specific node

                    .Where(p => p.Attribute("name").Value == "F22");
    Console.WriteLine(con);


}