Как получить позицию (индекс по порядку) элемента XML с помощью LINQ? - PullRequest
2 голосов
/ 08 ноября 2011

У меня есть 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, мне нужно извлечь элемент 4-й главы из документа XML.

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 ]

10 голосов
/ 08 ноября 2011

Ну, для начала, я не думаю, что вы хотели второго потомка в целом - вы хотели вторую главу , что не обязательно то же самое. К счастью, это легко сделать:

// 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 голос
/ 21 ноября 2013

Другой правильный ответ, хотя ответ Джона Скита более эффективен, это код:

chapter.ElementsBeforeSelf().Count()
0 голосов
/ 08 ноября 2011

Используя обозначение метода расширения, вы можете использовать вызов Select(), который предоставит вам индекс текущего элемента, например:

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

После этого вы сможете получить доступ к индексу анонимного типав любом следующем операторе linq.

...