Export (0) Print
Expand All
1 out of 1 rated this helpful - Rate this topic

Querying an XDocument vs. Querying an XElement

When you load a document via XDocument.Load, you will notice that you have to write queries slightly differently than when you load via XElement.Load.

When you load an XML document into an XElement via XElement.Load, the XElement at the root of the XML tree contains the root element of the loaded document. However, when you load the same XML document into an XDocument via XDocument.Load, the root of the tree is an XDocument node, and the root element of the loaded document is the one allowed child XElement node of the XDocument. The LINQ to XML axes operate relative to the root node.

This first example loads an XML tree using Load. It then queries for the child elements of the root of the tree.

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

As expected, this example produces the following output:

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

The following example is the same as the one above, with the exception that the XML tree is loaded into an XDocument instead of an XElement.

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

This example produces the following output:

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

Notice that the same query returned the one Root node instead of the three child nodes.

One approach to dealing with this is to use the Root property before accessing the axes methods, as follows:

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

This query now performs in the same way as the query on the tree rooted in XElement. The example produces the following output:

Querying tree loaded with XDocument.Load
----
<Child1>1</Child1>
<Child2>2</Child2>
<Child3>3</Child3>
Show:
© 2014 Microsoft. All rights reserved.