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.