LINQ to XML: как выбрать следующий элемент - PullRequest
14 голосов
/ 25 февраля 2011

У меня есть файл plist из приложения для iPhone.Вот как это выглядит ниже:

<plist version="1.0">
  <dict>
    <key>barcodes</key>
    <array>
      <string>JF893J89FJ-66666</string>
      <string>JF893J89FJ-55555</string>
    </array>
    <key>currentStep</key>
    <integer>1</integer>
    <key>dateFinished</key>
    <date>2010-05-10T18:33:25Z</date>
    <key>dateStarted</key>
    <date>2010-05-10T18:33:25Z</date>
    <key>description</key>
    <string>TEST</string>
    <key>geoRequired</key>
    <string>N</string>
    <key>inProgress</key>
    <string>N</string>
    <key>jobID</key>
    <integer>10085</integer>
    <key>jobSteps</key>
    <array>
      <dict>
        <key>label</key>
        <string>TEST</string>
        <key>response</key>
        <string>matt hudson</string>
        <key>stepID</key>
        <integer>1103</integer>
        <key>typeID</key>
        <integer>4</integer>
      </dict>
    </array>
  </dict>
</plist>

Мне нужно получить массив после jobSteps.

У меня пока есть это:

XDocument xml = XDocument.Load(rri.Response);

var q = from elements in xml.Descendants("plist").Descendants("dict")
        where elements.Value == "jobSteps"
        select elements;

Но мне нужно получитьследующий элемент после элемента, в котором есть jobSteps.

Ответы [ 4 ]

16 голосов
/ 25 февраля 2011

Мне не совсем понятно, подходит ли вам решение Адама, но если нет, вы можете посмотреть на свойство NextNode :

Получает следующего братаузел этого узла.

Например, здесь печатается элемент массива:

using System;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XDocument doc = XDocument.Load("test.xml");
        foreach (var element in doc.Descendants("key")
                                   .Where(x => (string) x == "jobSteps"))
        {
            Console.WriteLine(element.NextNode);
        }
    }
}

Обратите внимание, что пропускается пробел между элементами - но если было любой текст между этим и массивом, он не будет работать - так что вы хотели бы:

Console.WriteLine(element.NodesAfterSelf().OfType<XElement>().First());
5 голосов
/ 25 февраля 2011

РЕДАКТИРОВАТЬ

Я полагаю, что это даст вам элемент после узла jobSteps:

XElement elementAfterJobsteps = xml.Descendants("plist").FirstOrDefault().Descendants("jobSteps").FirstOrDefault().ElementsAfterSelf().FirstOrDefault();

END EDIT

foreach (XElement El in xml.Descendants("plist")) {
        var localResults = 
            from elements in El.Descendants("dict")
            where elements.Value == "jobSteps"
            select elements;

       //process localResults 
 }

Или, что еще проще, попробуйте синтаксис метода

 foreach (XElement El in xml.Descendants("plist")) {
    var localResults = El.Descendants("dict").Where(dict => dict.Value == "jobSteps");

    //process localResults 
 }
2 голосов
/ 25 февраля 2011
var q = xml
        .Descendants("plist")
        .Descendants("dict")
        .Where(item => item.Value == "jobSteps")
        .Select(item => item.NextNode)
        .SingleOrDefault() // add this if you expect single match
        ;

q будет либо отдельным узлом массива, либо последовательностью узлов массива в зависимости от того, используете ли вы SingleOrDefault().

1 голос
/ 25 февраля 2011
var q = (from key in xml.Descendants("key")
            where key.Value == "jobSteps"
            from array in xml.Descendants("array")
            select key.NodesAfterSelf() // In all nodes after <key>jobSteps</key>
                    .OfType<XElement>() // which are elements
                    .Where(element => element.Name == "array") // and name is array,
                    .First() // select first of them
        ).First(); // and select first of whatever is found

ПРИМЕЧАНИЕ. Приведенный выше код может выдать InvalidOperationException при вызове First(), если результат не найден.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...