linq to xml получить все дочерние узлы - PullRequest
2 голосов
/ 27 января 2012

Я пытаюсь запросить файл web.Config, содержащий записи WCF.

В узле <service> есть name attribute, с которым я пытаюсь найти соответствие. Пока что мой код работал при сопоставлении, но моя проблема в том, что он возвращает только 1 из <endpoint> узлов.

Например, у меня может быть этот фрагмент XML:

<service name="a">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
<endpoint>3</endpoint>
</service>
<service name="b">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
</service>

Каждый раз, когда я получаю совпадение, я хочу, чтобы он отображал все дочерние узлы <endpoint> для этого совпадения.

Это код, который у меня есть:

        IEnumerable<XElement> xmlURL =
            from el in xmlFile.Root.Descendants("service")
            where (string)el.Attribute("name") == serviceString
            select el.Element("endpoint");

        Console.WriteLine("Start: " + serviceString);
        foreach (XElement el in xmlURL)
        {
            Console.WriteLine(el);
        }
        Console.WriteLine("End: " + serviceString + "\n\n");

В настоящее время при совпадении отображается только 1 конечная точка.

1 Ответ

6 голосов
/ 27 января 2012

Я думаю, вы хотите это:

    IEnumerable<XElement> xmlURL =
        from el in xmlFile.Root.Descendants("service")
        where (string)el.Attribute("name") == serviceString
        select el.Descendants("endpoint");

    Console.WriteLine("Start: " + serviceString);
    foreach (XElement el in xmlURL)
    {
        Console.WriteLine(el);
    }
    Console.WriteLine("End: " + serviceString + "\n\n");

Обратите внимание, что я выбираю el.Descendants() вместо Element(), который будет возвращать только первый матч (http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx).

** ОБНОВЛЕНИЕ **

Я думаю, что это то, что вы хотите, потому что у вас есть только один конкретный матч.

IEnumerable<XElement> xmlURL = 
    (from el in doc.Root.Descendants("service")
    where el.Attribute("name").Value == serviceString
    select el).First().Descendants();

Таким образом, результатом запроса LINQ, как говорит вам компилятор, является IEnumerable из IEnumerables, поэтому я беру First() результат, который дает мне теперь IEnumerable<XElement>, а затем мы вызываем Descendants() для этого, что даетВы IEnumerable конечной точки XElement.

Также обратите внимание, что здесь я использовал Value свойство XAttribute, вы не можете просто привести XAttribute к строке, выЯ должен использовать это свойство Value. Я не уловил его в своем первоначальном ответе копирования / вставки.

** ОБНОВЛЕНИЕ 2 **

Приведенный выше запросМожет быть, немного легче понять, как это:

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();

** ОБНОВЛЕНИЕ 3 **

Существует также потенциал для NRE на attribute соответствие, так что опять это, вероятно, еще лучше версия.=)

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name") != null && x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...