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 :
1: string xmls = @"
2: <root>
3: <node>
4: <id>1</id>
5: </node>
6: <node>
7: <id>2</id>
8: </node>
9: <node>
10: <id>3</id>
11: <innernode>
12: <id>3.1</id>
13: </innernode>
14: <innernode>
15: <id>3.2</id>
16: </innernode>
17: </node>
18: <node>
19: <id>4</id>
20: </node>
21: </root>";
ed il seguente frammento di codice che utilizza la classe XDocument.
1: XDocument xdoc = XDocument.Parse(xmls);
2:
3: XElement[] app1 = xdoc.Root.Descendants().ToArray<XElement>();
4: 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

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).

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.