Linq

XElement.Descendants() versus XElement.Elements()

Le classi XDocument e XElement forniscono due metodi che, a prima vista, sembrano dover fornire un risultato molto simile ma nei fatti così non è. I metodi in questione sono :

  • Descendants() : ritorna tutti i “discendenti” del document root/elemento oppure quelli con uno specifico nome (se passato come parametro);
  • Elements() : ritorna i “figli” diretti del document root/elemento oppure quelli con uno specifico nome (se passato come parametro);

Consideriamo la seguente stringa XML :

string xmls = @"
    <root>
        <node>
            <id>1</id>
        </node>
        <node>
            <id>2</id>
        </node>
        <node>
            <id>3</id>
            <innernode>
                <id>3.1</id>
            </innernode>
            <innernode>
                <id>3.2</id>
            </innernode>
        </node>
        <node>
            <id>4</id>
        </node>
    </root>";

ed il seguente frammento di codice che utilizza la classe XDocument.

XDocument xdoc = XDocument.Parse(xmls);

XElement[] app1 = xdoc.Root.Descendants().ToArray<XElement>();
XElement[] app2 = xdoc.Root.Elements().ToArray<XElement>();

In entrambi i casi facciamo ritornare un array con i nodi individuati dai due metodi.

Di seguito uno screenshot del loro contenuto

6646.XDocument_1_445068F5

Con il metodo Descendants() vengono recuperati tutti i discendenti a qualsiasi livello e quindi per esempio, considerando il nodo più complesso, anche il nodo con id = 3 (posizione 4 nell’array) ma successivamente tutti i suoi discendenti a tutti i livelli (dalla posizione 5 alla posizione 9 nell’array).

1538.XDocument_2_037E6CC6

Viceversa, con il metodo Elements() otteniamo solo i figli diretti del nodo root del documento. Per poter ricavare i loro corrispondenti ulteriori nodi figli, dovremo necessariamente eseguire un’ulteriore interrogazione su ciascuno di essi.