C# 根据后代节点的属性选择节点的最佳 LINQ-to-XML 查询?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/787240/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:08:42  来源:igfitidea点击:

Best LINQ-to-XML query to select nodes based on properties of descendant nodes?

c#xmllinq-to-xml

提问by Gayle

I have the following XML document:

我有以下 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>

I'm trying to select all the "Parents" with a Child who has at least two children ("Grandchild") of his/her own. Note that I'm notlooking for "Parents" with at least two "Grandchild[ren]".

我试图选择所有“父母”,孩子至少有两个孩子(“孙子”)。请注意,我不是在寻找至少有两个“孙[ren]”的“父母”。

The following LINQ query works, but I've a feeling it's not the most elegant.

以下 LINQ 查询有效,但我感觉它不是最优雅的。

IEnumerable<XElement> parents = (from c in familyTreeElement.Descendants("Child")
                                 where c.Elements().Count() > 1
                                 select c.Parent).Distinct();

Is there a better way to specify this?

有没有更好的方来指定这一点?

采纳答案by Marc Gravell

Ahh the edit (2 grand-children) helps ;-p

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

While XDocumentis useful, at times I miss XPath/XQuery. With XmlDocumentyou could just use doc.DocumentElement.SelectNodes("Parent[Child/Grandchild[2]]").

虽然XDocument很有用,但有时我会想念 XPath/XQuery。有了XmlDocument你就可以使用doc.DocumentElement.SelectNodes("Parent[Child/Grandchild[2]]").

回答by mqp

I don't know the "SQL-like" syntax enough to guarantee that I'll get the syntax right if I write it that way, but you want to use .Any()instead of .Count(), and if you select in a different manner, you don't need the Distinct()at the end. Try this:

我不太了解“类似 SQL”的语,无保证如果我这样写,我会得到正确的语,但是您想使用.Any()代替.Count(),如果您以不同的方式进行选择,则不会不需要Distinct()最后。尝试这个:

IEnumerable<XElement> parents =
    familyTreeElement.Elements("Parent").Where(
        parent => parent.Elements("Child").Any(
            child => child.Elements().Count() >= 2));

EDIT:If you want to ensure that there are at least 2, you do pretty much have to use .Count().

编辑:如果你想确保至少有 2 个,你几乎必须使用.Count().

回答by Jon Skeet

Hmmm... I'm finding it hard to get my head round it exactly :)

嗯......我发现很难完全理解它:)

Normally to find out if there are anyelements, I'd use Any- but you want to see if there are at least twoelements. We still don't need to use Countthough - because there being at least two elements is the same as skipping an element and seeing if there are still any. So...

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

var parents = familyTreeElement.Elements("Parent")
    .Where(parent => parent.Elements("Child").Any(
                     child => child.Elements("Grandchild").Skip(1).Any()));

I think that works - and actually it doesn't read toobadly:

我认为这是有效的 - 实际上它读起来并不太糟糕:

For each parent, see whether anyof there children has any(grand)children after ignoring the first (grand)child.

对于每一个家长,看有无任何有孩子有任何忽略第一(大)后的孩子(大)的儿童。

I suspect using XPath (as per Marc's answer) would be the most readable option though.

我怀疑使用 XPath(根据 Marc 的回答)将是最易读的选项。