XDocument- und XElement-Abfrage im Vergleich (LINQ to XML)

Die Abfrage, die Sie beim Laden eines Dokuments über XDocument.Load schreiben, unterscheidet sich geringfügig von dem, was Sie beim Laden über XElement.Load schreiben.

Gegenüberstellung von XDocument.Load und XElement.Load

Beim Laden eines XML-Dokuments in ein XElement über XElement.Load enthält das XElement am Stamm der XML-Struktur das Stammelement des geladenen Dokuments. Wenn Sie jedoch dasselbe XML-Dokument über XDocument in ein XDocument.Load laden, ist der Stamm der Struktur ein XDocument-Knoten, und das Stammelement des geladenen Dokuments ist der einzige zulässige untergeordnete XElement-Knoten des XDocument. Die LINQ to XML-Achsen agieren relativ zum Stammknoten.

Beispiel: Laden einer XML-Struktur mithilfe von XElement.Load und dann Abfragen nach untergeordneten Elementen

Dieses erstes Beispiel lädt eine XML-Struktur mit Load. Anschließend fragt es die untergeordneten Elemente des Stamms der Struktur ab:

// Create a simple document and write it to a file
File.WriteAllText("Test.xml", @"<Root>
    <Child1>1</Child1>
    <Child2>2</Child2>
    <Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XElement.Load");
Console.WriteLine("----");
XElement doc = XElement.Load("Test.xml");
IEnumerable<XElement> childList =
    from el in doc.Elements()
    select el;
foreach (XElement e in childList)
    Console.WriteLine(e);
' Create a simple document and  write it to a file
File.WriteAllText("Test.xml", "<Root>" + Environment.NewLine + _
    "    <Child1>1</Child1>" + Environment.NewLine + _
    "    <Child2>2</Child2>" + Environment.NewLine + _
    "    <Child3>3</Child3>" + Environment.NewLine + _
    "</Root>")

Console.WriteLine("Querying tree loaded with XElement.Load")
Console.WriteLine("----")
Dim doc As XElement = XElement.Load("Test.xml")
Dim childList As IEnumerable(Of XElement) = _
        From el In doc.Elements() _
        Select el
For Each e As XElement In childList
    Console.WriteLine(e)
Next

Dieses Beispiel erzeugt die folgende Ausgabe:

Querying tree loaded with XElement.Load
----
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>

Beispiel: Laden einer XML-Struktur mithilfe von XDocument.Load und dann Abfragen nach untergeordneten Elementen

Im nächsten Beispiel wird derselbe Vorgang wie zuvor ausgeführt, aber die XML-Struktur wurde in XDocument und nicht in XElement geladen.

// Create a simple document and write it to a file
File.WriteAllText("Test.xml", @"<Root>
    <Child1>1</Child1>
    <Child2>2</Child2>
    <Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XDocument.Load");
Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
    from el in doc.Elements()
    select el;
foreach (XElement e in childList)
    Console.WriteLine(e);
' Create a simple document and  write it to a file
File.WriteAllText("Test.xml", "<Root>" + Environment.NewLine + _
    "    <Child1>1</Child1>" + Environment.NewLine + _
    "    <Child2>2</Child2>" + Environment.NewLine + _
    "    <Child3>3</Child3>" + Environment.NewLine + _
    "</Root>")

Console.WriteLine("Querying tree loaded with XDocument.Load")
Console.WriteLine("----")
Dim doc As XDocument = XDocument.Load("Test.xml")
Dim childList As IEnumerable(Of XElement) = _
        From el In doc.Elements() _
        Select el
For Each e As XElement In childList
    Console.WriteLine(e)
Next

Dieses Beispiel erzeugt die folgende Ausgabe:

Querying tree loaded with XDocument.Load
----
<Root>
  <Child1>1</Child1>
  <Child2>2</Child2>
  <Child3>3</Child3>
</Root>

Dieselbe Abfrage hat also diesmal nicht die drei untergeordneten Knoten, sondern den einen Root-Knoten zurückgegeben.

Ein Ansatz für den Umgang mit diesem Verhalten besteht darin, vor dem Zugreifen auf die Achsenmethoden die Root-Eigenschaft zu verwenden, wie im folgenden Beispiel gezeigt:

// Create a simple document and write it to a file
File.WriteAllText("Test.xml", @"<Root>
    <Child1>1</Child1>
    <Child2>2</Child2>
    <Child3>3</Child3>
</Root>");

Console.WriteLine("Querying tree loaded with XDocument.Load");
Console.WriteLine("----");
XDocument doc = XDocument.Load("Test.xml");
IEnumerable<XElement> childList =
    from el in doc.Root.Elements()
    select el;
foreach (XElement e in childList)
    Console.WriteLine(e);
' Create a simple document and  write it to a file
File.WriteAllText("Test.xml", "<Root>" + Environment.NewLine + _
    "    <Child1>1</Child1>" + Environment.NewLine + _
    "    <Child2>2</Child2>" + Environment.NewLine + _
    "    <Child3>3</Child3>" + Environment.NewLine + _
    "</Root>")

Console.WriteLine("Querying tree loaded with XDocument.Load")
Console.WriteLine("----")
Dim doc As XDocument = XDocument.Load("Test.xml")
Dim childList As IEnumerable(Of XElement) = _
        From el In doc.Root.Elements() _
        Select el
For Each e As XElement In childList
    Console.WriteLine(e)
Next

Diese Abfrage ist jetzt genauso schnell wie die Abfrage für die Struktur mit dem XElement als Stammelement.

Dieses Beispiel erzeugt die folgende Ausgabe:

Querying tree loaded with XDocument.Load
----
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>