2011-11-08 30 views
2

我有XML正是這樣的格式:如何使用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> 

在C#中使用LINQ,我需要能夠得到一個特定位置或索引的XML元素的基礎上,功能state.getChapterNumber的值( )。例如,如果值爲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()。值== state.getChapterNumber()' –

回答

9

好吧,首先,我不認爲你想要第二個後裔整體 - 你想第二個,這不一定是同一件事。幸運的是這很容易做到:

// 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... 

編輯:對於詩歌數量,使用的Select超載它提供了元素索引:

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

我不認爲它使多大意義的經文親自在段落中有第一個和最後一個詩句。這不是該詩節的特色,是嗎?

+0

你簡單的編程技術也有幫助。也許你可以幫助弄清楚如何讓linq返回每個'select new'的迭代計數。因此,我將有'VerseNumber = THE ITERATION',而不是上面的行。我會寫一些像'VerseNumber = verse.Index()。Value,' –

+0

@GuyMicciche:編輯... –

+0

我的朋友,你救了我的命!我正在做一個慶祝的飲料!這就是我所做的(都感謝你)。我做了一個名爲'Verse'的課程,其中包含我所有的變量。然後我使用你的技術。元素(),book.Descendants(「c」)。ElementAt(state.GetChapter() - 1).Descendants(「p」)。Elements() .Select((element,index)=> new Verse { VerseNumber =(index + 1).ToString(), ScriptureText = element.Value });'這工作完美!非常感謝! –

0

通過使用擴展方法的符號可以使用Select()調用,將提供當前元素的這樣的指標:

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

之後,你可以比訪問匿名類型的索引任何以下linq聲明。

+0

在我的linq語句後的'從'語句,我的where語句看起來像這樣:'where book.Decendants(「c」)。Index == state.GetChapterNumber()'基本上,我從一個函數中獲取一個值,以根據該值獲取相應的xml元素位置。你能幫忙嗎,看來你有正確的方向。 –

+0

我有更大的問題。我在哪裏有'VerseNumber = verse.Attribute(「n」)。Value,'我每次都需要VerseNumber值來遍歷每章XML文件中的節數。好傢伙。 –

0

正確的答案,雖然喬恩斯基特的答案是方式更有效,這是代碼:

chapter.ElementsBeforeSelf()COUNT()