LINQ to XML: как получить только прямых потомков XElement? - PullRequest
17 голосов
/ 04 августа 2009
Dim xml = <Root>
            <Parent id="1">
              <Child>Thomas</Child>
            </Parent>
            <Parent id="2">
              <Child>Tim</Child>
              <Child>Jamie</Child>
            </Parent>
          </Root>

Dim parents = xml.Elements

В этом случае children включает в себя все родительские элементы и все дочерние элементы. Как лучше всего захватить только прямых потомков из <Root>?

Должен ли я написать запрос LINQ, который выбирает элементы, где parent = <Root>? Или есть какой-то встроенный метод, который мне не хватает, который может получить это для меня?

РЕДАКТИРОВАТЬ: У меня была путаница между XElement.Elements и XElement.Descendants. Как указал Рубен Бартелинк, XElement.Elements даст мне именно то, что я искал.

Ответы [ 5 ]

18 голосов
/ 04 августа 2009

Краткое резюме - вы хотите:

xml.Elements.Select(function(element) new XElement(element.Name,element.Attributes))

Первый ответ:

XElement.Descendants, или это вопрос с подвохом? : P Вот пример использования Потомков здесь

Пересмотренный ответ, спасибо Тормод - что-то не так!:

Элементы дают прямых потомков, как вы ищете. Потомки дают полную иерархию [как вы утверждаете, элементы делает]. (Пример, с которым я связан, проясняет это. Извиняюсь за путаницу!

Итак, наконец, то, что вы ищете (на этот раз в VB):

Dim xml = <Root>
        <Parent id="1">
          <Child>Thomas</Child>
        </Parent>
        <Parent id="2">
          <Child>Tim</Child>
          <Child>Jamie</Child>
        </Parent>
      </Root>

REM All nodes two levels down in the hierarchy
Dim level2Nodes = xml.Elements.SelectMany(function(element) element.Elements)
level2Nodes.Dump

REM All Child nodes, no matter where they are:
Dim children = xml.Descendants("Child")

Каждый из которых даст вам 3 `` `элемента по разным причинам, описанным в REM.

(Вставьте вышеприведенное непосредственно в LINQPad в режиме оператора VB)

Теперь я вижу, что может вас смущать - когда вы используете Elements и просматриваете его в визуализаторе, вы все еще видите детей: -

Dim parents = xml.Elements

Если вам нужны только реальные имена, вы можете использовать что-то вроде:

Dim parentNames = xml.Elements.Select(function(element) element.Name)

Обратите внимание, что в каждом из этих случаев вы получаете два результата.

Если вы действительно хотите раздеть детей, вы хотите:

Dim parentElements = xml.Elements.Select(function(element) new XElement(element.Name,element.Attributes))

Можете ли вы расширить свой вопрос, чтобы показать, что вы действительно ищете?

17 голосов
/ 04 августа 2009

XElement.Elements получает коллекцию дочерних элементов. Например ...

var s = @"<root>
             <e1>
                 <e2>
                 </e2>
             </e1>
             <e1>
                 <e2>
                 </e2>
             </e1>
             <e1>
                 <e2>
                 </e2>
             </e1>
          </root>";

var doc = XElement.Load( new StringReader(s) );

Console.WriteLine( doc.Elements().Count() ); // 3
Console.WriteLine( doc.Descendants().Count()); //6
3 голосов
/ 06 января 2014

Используя Linq, мы можем это сделать.

string s = "<Root><Parent id=\"1\"><Child>Thomas</Child></Parent><Parent id=\"2\"><Child>Tim</Child><Child>Jamie</Child></Parent></Root>";
XDocument xdoc = XDocument.Parse(s);
foreach (XElement DirectChild in xdoc.Descendants().Where(child => child.Parent == xdoc.Root))
{
//Do stuff here
}

Надеюсь, это поможет. Спасибо.

0 голосов
/ 04 августа 2009

Если все прямые потомки имеют одинаковое известное имя элемента и это имя элемента не может отображаться на другом уровне, вы можете использовать xml.Descendants ("Parent").

0 голосов
/ 04 августа 2009

Почему бы не использовать XPath?

Dim myXML As var = New XmlDocument()
myXML.Load(myXML.xml)

For Each node As XmlNode In myXML.SelectNodes("//")
    Dim myVar As var = node.SelectSingleNode("Parent").InnerText
Next

Возьми это с щепоткой соли - я только что преобразовал это из C # в VB.

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