选择特定的元素

本文关键字:元素 选择 | 更新日期: 2023-09-27 18:15:54

基本上,我很难理解我在这里哪里出错了。

基本上,我有以下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查询方面出了什么问题,这样我就可以选择特定根的所有后代?

选择特定的元素

如果我正确理解了您的问题,您正试图提取属于给定CustDirectory的所有Person元素。在这种情况下,您应该使用类似以下的内容:

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

除了ToStr部分外,一切看起来都很正常。

要选择CustDirectory下的Person元素,名称为Name2,你需要把Where放在上面,像这样:

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

注意,我将Element("CustDirectory")更改为Elements("CustDirectory")

一开始你不需要Element("Directory"),因为e本身已经引用了<Directory>(不同的情况下,如果eXDocument而不是XElement,如你在评论中所说)。这个例子能够返回<Person>节点给出问题中的示例XML:

var e = XElement.Parse("...");
var con = e.Elements("CustDirectory")
           .Where(p => p.Attribute("name").Value == "Name2")
           .Elements("Person");
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);

}