LINQ to XML Descendants Versus Elements

LINQ to XML is the greatest thing for working with XML. If you’re doing just about anything XML in .NET, you should probably be using it. One of the points I missed in the passed was the difference between LINQ to XML’s Elements and Descendants methods. Both methods are used to retrieve sub-elements, but the distinction is that Elements will only search direct child nodes whereas Descendants will search recursively.

Consider the following XML:

<root>
  <house>
    <address>123 Number Lane</address>
  </house>
  <business>
    <address>100 Fun Drive</address>
  </business>
</root>

If I want to retrieve a list of all addresses, I can use Descendants.

var addresses = xml.Descendants("address");

// Result:
// <address>123 Number Lane</address>
// <address>100 Fun Drive</address>

I can’t do this with Elements.

var addresses = xml.Elements("address");

// Result:
// (Nothing!)

If I want to accomplish this with Elements, I need to first get all children from the root and then retrieve their addresses.

// You should probably just use Descendants()...
addresses = xml.Root
	.Elements()
	.SelectMany(x => x.Elements("address"));

// Result:
// <address>123 Number Lane</address>
// <address>100 Fun Drive</address>

Elements is good for getting values from a specific path, though. For example, if you want to retrieve only the house addresses, you could do the following:

addresses = xml.Root
	.Elements("house")
	.SelectMany(x => x.Elements("address"));

// Result:
// <address>123 Number Lane</address>

Note, however, that the same* task can be accomplished using Descendants, too!

addresses = xml.Root
	.Descendants("house")
	.SelectMany(x => x.Descendants("address"));

// Result:
// <address>123 Number Lane</address>

*Of course, this “same” functionality is entirely dependent on the structure of the XML and what you’re trying to accomplish. If there were child elements beneath “house” that had child addresses, Descendants would snag those, which may or may not be desirable depending on your needs.

So, in summary, use Elements when you want to search and retrieve only from immediate child elements (perhaps it should have been named “Children!”), and use Descendants when you want to search and retrieve from all descendant elements. I generally stick to Descendants because I can “jump” directly to the node(s) that I’m looking for without having to step though the path. If I only care about a specific path, I can specify it with Descendants the same as I would with Elements. I only use Elements if I needed to find elements at a specific level or want to ignore matching sub-elements.

Advertisements

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s