Я бы использовал тот факт, что вы можете вызвать Elements
или существующую последовательность, поэтому:
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();
Возможно, вы даже захотите добавить метод расширения где-нибудь:
public static IEnumerable<XElement> WithName(this IEnumerable<XElement> elements,
string name)
{
this elements.Where(x => (string) x.Attribute("Name") == name);
}
Затем вы можете переписать запрос как:
var template = doc.Descendants("Application").WithName(applicationName)
.Elements("Section").WithName(sectionName)
.Elements("Template").WithName(templateName)
.FirstOrDefault();
... что, я думаю, вы согласитесь, вполне читабельно:)
Обратите внимание, что использование приведения XAttribute
к string
вместо использования свойства Value
означает, что любые элементы без атрибута Name
просто эффективно игнорируются, а не вызывают NullReferenceException
.