C# 根据子节点的属性选择节点的最佳LINQ到XML查询?

C# 根据子节点的属性选择节点的最佳LINQ到XML查询?,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我有以下XML文档: <?xml version="1.0" encoding="UTF-8"?> <FamilyTree> <Parent name="Ken"> <Child name="Lorna"> <Grandchild name="Andrew"/> <Grandchild name="Brian"/> </Child> <Child name

我有以下XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<FamilyTree>
  <Parent name="Ken">
    <Child name="Lorna">
      <Grandchild name="Andrew"/>
      <Grandchild name="Brian"/>
    </Child>
    <Child name="Mike">
      <Grandchild name="Ann"/>
      <Grandchild name="Beth"/>
    </Child>
  </Parent>
  <Parent name="Norma">
    <Child name="Owen">
      <Grandchild name="Charles"/>
    </Child>
    <Child name="Peter">
      <Grandchild name="Charlotte"/>
    </Child>
  </Parent>
  <Parent name="Quinn">
    <Child name="Robert">
      <Grandchild name="Debbie"/>
      <Grandchild name="Eric"/>
    </Child>
    <Child name="Susan">
      <Grandchild name="Frank"/>
    </Child>
  </Parent>
  <Parent name="Tom">
    <Child name="Ursula">
      <Grandchild name="George"/>
      <Grandchild name="Harriet"/>
    </Child>
    <Child name="Victor">
      <Grandchild name="Ian"/>
      <Grandchild name="Juliet"/>
    </Child>
  </Parent>
</FamilyTree>

我试图选择所有的“父母”,他们的孩子至少有两个自己的孩子(“孙子”)。请注意,我不是在寻找至少有两个“孙子(孙女)”的“父母”

下面的LINQ查询可以工作,但我觉得它不是最优雅的

IEnumerable<XElement> parents = (from c in familyTreeElement.Descendants("Child")
                                 where c.Elements().Count() > 1
                                 select c.Parent).Distinct();
IEnumerable parents=(来自familyTreeElement.subjections(“子”)中的c)
其中c.Elements().Count()>1
选择c.Parent).Distinct();
有没有更好的方法来指定这一点?

我对“类似SQL”的语法不太了解,无法保证如果我用这种方式编写语法,我会得到正确的语法,但是您希望使用
.Any()
而不是
.Count()
,如果您以不同的方式选择,那么最后就不需要
Distinct()
。试试这个:

IEnumerable<XElement> parents =
    familyTreeElement.Elements("Parent").Where(
        parent => parent.Elements("Child").Any(
            child => child.Elements().Count() >= 2));
IEnumerable双亲=
familyTreeElement.Elements(“父项”)。其中(
parent=>parent.Elements(“子”).Any(
child=>child.Elements().Count()>=2));

编辑:如果要确保至少有两个,您几乎必须使用
.Count()。。。我发现很难完全理解它:)

通常,为了找出是否有任何元素,我会使用
any
——但您想知道是否至少有两个元素。但是我们仍然不需要使用
Count
,因为至少有两个元素与跳过一个元素并查看是否仍然存在相同。所以

var parents = familyTreeElement.Elements("Parent")
    .Where(parent => parent.Elements("Child").Any(
                     child => child.Elements("Grandchild").Skip(1).Any()));
我认为这很管用——实际上读起来也不算太糟:

对于每个家长,在忽略第一个(大)子代后,查看其中的任何子代是否有任何(大)子代

不过,我怀疑使用XPath(根据Marc的回答)将是最具可读性的选择。

啊,编辑(两个孙子)有帮助-p


虽然
XDocument
很有用,但有时我会错过XPath/XQuery。使用
XmlDocument
您可以只使用
doc.DocumentElement.SelectNodes(“父[子/孙[2]])

第一条注释-这是检查至少两个子项…谢谢。我已经纠正了打字错误。我确实想检查至少两个孩子。有什么理由不使用XPathExtensions吗?是的,对不起。打字错误。在试图解释这一切时,我想得太多了。familyTreeElement.XPathSelectElements(“父[子/孙[2]]);似乎很管用。Count()是为懦夫准备的-你可以不用它;)这是一个聪明的方法,可以不用计算就知道是否有两个+1.我以前没想过,但这正是我们人类应该做的。如果我们被要求确保一个罐头里至少有十块饼干,我们只会看前十块饼干:)