如何使用LINQ获取XML元素的位置(按顺序索引)?

时间:2011-11-08 07:28:27

标签: c# xml linq silverlight-4.0 linq-to-xml

我的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>

在使用Linq的C#中,我需要能够根据函数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
             };

请帮助,这非常重要,并且已经让我好几天了。我想做的就是能够从书中选择的任何章节中获得经文。

3 个答案:

答案 0 :(得分:10)

首先,我不认为你想要第二个后代整体 - 你想要第二个,这不一定是同一个东西。幸运的是,这很容易做到:

// 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
                            });

我认为每一个诗节都没有多大意义,因为这个段落中的第一节和最后一节是个人的。这不是那节经文的特色,是吗?

答案 1 :(得分:1)

另一个正确的答案,虽然Jon Skeet的回答更有效,但这段代码是:

chapter.ElementsBeforeSelf().Count()

答案 2 :(得分:0)

通过使用扩展方法表示法,您可以使用Select()调用,它将为您提供当前元素的索引,如下所示:

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

之后,您可以在以下任何linq语句中访问匿名类型的索引。