I would use the fact that you can call Elements or an existing sequence, so:
var template = doc.Descendants("Application") .Where(x => (string) x.Attribute("Name") == applicationName) .Elements("Section") .Where(x => (string) x.Attribute("Name") == sectionName) .Elements("Template") .Where(x => (string) x.Attribute("Name") == templateName) .FirstOrDefault();
You might also want to add an extension method:
public static IEnumerable<XElement> WithName(this IEnumerable<XElement> elements, string name) { this elements.Where(x => (string) x.Attribute("Name") == name); }
Then you can rewrite the request as:
var template = doc.Descendants("Application").WithName(applicationName) .Elements("Section").WithName(sectionName) .Elements("Template").WithName(templateName) .FirstOrDefault();
... which, I think, you will agree, is quite readable :)
Note that using casting XAttribute to string instead of using the Value property means that any elements without the Name attribute are simply ignored and not cause a NullReferenceException .
source share