Vergleich zwischen dem Abfragen eines "XDocument" und dem Abfragen eines „XElement“ (C#)

Das Schreiben von Abfragen für Dokumente, die über XDocument.Load geladen werden, unterscheidet sich geringfügig vom Schreiben von Abfragen für Dokumente, die über XElement.Load geladen werden.

Vergleich zwischen "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.

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

Wie zu erwarten, erzeugt dieses Beispiel die folgende Ausgabe:

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

Das folgende Beispiel entspricht dem vorhergehenden Beispiel, wobei hier die XML-Struktur nicht in ein XDocument, sondern in ein XElement geladen wird:

// 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);  

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

Diese Abfrage ist jetzt genauso schnell wie die Abfrage für die Struktur mit dem XElement als Stammelement. Das Beispiel führt zur folgenden Ausgabe:

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

Siehe auch

Basic Queries (LINQ to XML) (C#) (Standardabfragen (LINQ to XML) (C#))