2009-04-24 12 views
3

I次のXML文書を持っている:私は彼/彼女の自身の少なくとも2人の子供を持つ子供(「孫」)で、すべての「親」を選択しようとしている子孫ノードのプロパティに基づいてノードを選択するための最善のLINQ-to-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> 

。私はで、ではなく、少なくとも2人の "Grandchild [ren]"と "Parents"を探していることに注意してください。

次のLINQクエリが機能しますが、最もエレガントではないと感じました。

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

これを指定するより良い方法はありますか?

+0

最初のコメント - 少なくとも2人の子供をチェックしています... –

+1

ありがとうございます。私はタイプミスを修正しました。私は確かに少なくとも2人の子供をチェックしたい。 – Gayle

答えて

2

を;-pに役立ちます。 XmlDocumentでは、doc.DocumentElement.SelectNodes("Parent[Child/Grandchild[2]]")を使用できます。

+0

XPathExtensionsを使用しない理由は何ですか? –

+0

はい、申し訳ありません。タイプミス。それをすべて説明しようとするとあまりにも難しいと思っていた。 – Gayle

+0

@Jon - 真実、真実 - 私は彼らのために失明しているようです... –

0

文法を正しく書くためには、 "SQLのような"構文はわかりませんが、.Count()の代わりに.Any()を使い、異なる方法では、最後にDistinct()は必要ありません。

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

EDIT:この試してみてくださいあなたは、少なくとも2であることを確実にしたい場合はを、あなたはかなり.Count()を使用する必要があります。

+0

Count()は霊長類のためのものです - あなたはそれなしで離れていくことができます;) –

5

うーん...私はそれは難しい正確にラウンド私の頭を取得するために探しています:)

通常任意の要素があるかどうかを調べるために、私はAnyを使用したい - しかし、あなたが見たいですが少なくとも2つある場合は要素です。しかし、少なくとも2つの要素が存在するのは、要素をスキップしてまだ存在するかどうかを確認することと同じであるため、Countを使用する必要はありません。だから... ...

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

私が作品だと思います - 実際にそれはひどくあまりにををして読んでいません:それぞれの親のために

を、任意のが子供のが任意の(グランドを持っているかどうかを確認)子供を無視した後の子供たち。

私はXPath(Marcの答えによると)が最も読みやすいオプションだと思っています。 XDocumentは私は、XPath/XQueryを欠場回で、有用であるが、編集(2孫)ああ

+0

それは数えない2つがあるかどうかを見つける巧妙な方法です。 +1。 – mquander

+2

私はそれを前に考えていませんでしたが、それはまさに私たちが人間としてそれをやる方法です。スズの中に少なくとも10個のビスケットがあることを確認するように頼まれた場合、私たちは見た最初の10個まで見ています:) –

関連する問題