Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the XElement for the XML

Here's my XML File:

<Applications>
   <Application Name="Abc">
     <Section Name="xyz">
        <Template Name="hello">
         ...
         ....
         </Template>
      </Section>
   </Application>
   <Application Name="Abc1">
     <Section Name="xyz1">
        <Template Name="hello">
         ...
         ....
         </Template>
      </Section>
   </Application>

What I need to do is get the Template XElement from the given structure based upon the Name attribute of Template tag. The problem is there can be multiple template tags with same attribute Name. The Distinguishing factor is Application Name attribute value and section attribute value.

Currently I'm able to get the XElement by first getting Application Element based upon it's attribute, then Section based upon it's attribute and then finally template based upon it' name.

I wanted to know if there is a way to get it in one go.

like image 362
gizgok Avatar asked Jan 17 '23 14:01

gizgok


1 Answers

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 even want to add an extension method somewhere:

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 query as:

var template = doc.Descendants("Application").WithName(applicationName)
                  .Elements("Section").WithName(sectionName)
                  .Elements("Template").WithName(templateName)
                  .FirstOrDefault();

... which I think you'll agree is quite readable :)

Note that the use of casting XAttribute to string instead of using the Value property means that any elements without the Name attribute are just effectively ignored rather than causing a NullReferenceException.

like image 96
Jon Skeet Avatar answered Jan 27 '23 08:01

Jon Skeet