2011-11-08 15 views
2

私は、まさにこの形式のようなXMLがあります:LINQのを使用してC#ではLINQを使用してXML要素の位置(インデックス順)を取得する方法は?

<?xml version="1.0" encoding="utf-8"?> 
<book> 
    <chapter> 
     <verse>This is verse 1</verse> 
     <verse>This is verse 2</verse> 
     <verse>This is verse 3</verse> 
     <verse>This is verse 4</verse> 
    </chapter> 
    <chapter> 
     <verse>This is verse 1</verse> 
     <verse>This is verse 2</verse> 
    </chapter> 
    <chapter> 
     <verse>This is verse 1</verse> 
    </chapter> 
</book> 

を、私は(関数state.getChapterNumberの値に基づいて、特定の位置またはインデックスのXML要素を取得できるようにする必要があります)。たとえば、値が4の場合、XMLドキュメントから4番目の章の要素を取得する必要があります。

XDocument book = XDocument.Load(string.Format("Translations/NWT/{0}.xml", state.BookName)); 
var verses = from chapter in book.Decendants() 
      where state.getChapterNumber() == (WHAT DO I PUT HERE TO MATCH THE VALUE??) 
      from verse in chapter.Descendants("p").Elements() 
      select new 
      { 
       VerseNumber = verse.Attribute("n").Value, 
       Text = verse.Value, 
       LastVerseInParagraph = verse.Parent.Elements().LastOrDefault().Value, 
       FirstVerseInParagraph = verse.Parent.Elements().FirstOrDefault().Value 
      }; 

これは本当に重要であり、数日間私を抱きしめています。私がしたいのは、私が本で選んだ任意の章から詩を得ることだけです。

+0

なぜ私は 'chapter.Index()と言うことはできません。 Value == state.getChapterNumber() ' –

答えて

9

まず、2番目の子孫が欲しいとは思わないと思いますが、2番目のチャプターが必要です。これは必ずしも同じものではありません。幸いにもそれが行うのは簡単だ:

// Use 1 for the second chapter, 2 for "element 2" (i.e. the third element) etc 
var chapter = book.Descendants("chapter").ElementAt(1); 

var verses = from verse in chapter... 

EDIT:詩の数の場合は、要素のインデックスを提供Selectのオーバーロードを使用します。

var verses = chapter.Element("verse") 
        .Select((element, index) => new { 
           VerseNumber = index + 1, 
           Text = element.Value 
          }); 

私はすべてのそれはのための多くの理にかなっているとは思いません詩は、パラグラフの最初と最後の詩を個人的に持っています。それは本当にその詩の特徴ではありませんか?あなたはより任意の次に匿名型のインデックスにアクセスすることができます。その後

var indexedChapters = book.Decendants().Select((Chapter, Index) => new { Chapter, Index }); 

+0

あなたは簡単なプログラミングテクニックも手助けしました。おそらく、linqに 'select new'の反復回数を返す方法を理解するのを助けることができますので、上記の行の代わりに' VerseNumber = THE ITERATION 'を使用します。 'VerseNumber = verse.Index()。Value、' –

+0

@GuyMicciche:Edited ... –

+0

私の友人、あなたは私の人生を救った!私は今、お祝いのドリンクを作っています!ここに私がしたことがあります(あなたに感謝します)。私はすべての変数を含む 'Verse'というクラスを作りました。そして、私はあなたのテクニックをこのように使いました。 (要素、インデックス)=>新しい詩 { (要素、インデックス)=>新しい詩 ) VerseNumber =(index + 1).ToString()、 ScriptureText = element.Value });これは完全に機能しました!どうもありがとうございます! –

0

拡張メソッドの表記を使用することによって、あなたはあなたにこのような現在の要素のインデックスを提供しますSelect()コールを使用することができますlinqステートメント。

+0

質問を見つける私のlinqステートメントの後に 'ステートメント(ここでbook.Decendants( "c")。Index == state.GetChapterNumber() '基本的には、関数から値を取り出して、その値に基づいて対応するxml要素の位置を取得しています。あなたは助けてくれますか?あなたは正しい方向に私を持っているようです。 –

+0

私はより大きな問題があります。私は 'VerseNumber = verse.Attribute(" n ")。Value、'各章ごとにXMLファイル内の節の数を反復するために、毎回VerseNumber値が必要です。ああ少年。 –

0

正解ジョンスキートの答えは方法より効率的ではあるが、このコードは次のとおりです。

chapter.ElementsBeforeSelf()(カウント)

関連する問題