Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Using LINQ to XML to query XML data

DZone's Guide to

Using LINQ to XML to query XML data

· Database Zone
Free Resource

MongoDB Atlas is a database as a service that makes it easy to deploy, manage, and scale MongoDB. So you can focus on innovation, not operations. Brought to you in partnership with MongoDB.

LINQ to XML is a programming interface that lets the developers use LINQ (Language Integrated Query) to manage XML data. It simplifies a lot of XML data manipulation procedures, for example – node selection. In this article I am describing some ways to extract data from a XML file by executing queries a XML file.

Let’s take a look at an example first. I have a very simple XML file that contains data about a number of customers that only stores their ID and name:

<customers>  <customer id="84">    <name value="Sample Name" />  </customer>   <customer id="89">    <name value="Sample Name 2" />  </customer>   <customer id="80">    <name value="Sample Name 3" />  </customer></customers>

 

I’d like to select the node that has the customer ID equal to 80. Normally, before LINQ was a part of .NET, the way to do this would be going through each node in the file and checking the ID with the gelp of a loop. Like this:

XmlNode searched = null;XmlDocument doc = new XmlDocument();doc.Load(@"D:\Temporary\customers.xml");foreach (XmlNode node in doc.SelectNodes("/customers/customer")){    if (node.Attributes["id"].InnerText == "80")    {        searched = node;        break;    }}

On a generic example like mine, it will be a fast process. However, when there are hundreds of nodes, it might take some time to find the new one.

To do the same thing with LINQ to XML, I’d only build the query like this:

XElement main = XElement.Load(@"D:\Temporary\customers.xml");IEnumerable<XElement> searched =    from c in main.Elements("customer")    where (string)c.Attribute("id") == "80"    select c;

You will need to add a reference to System.Linq and System.Xml.Linq in order to use the code shown above.

This way, I am loading the contents of the file, and then I am looking for a collection of elements that fit my criteria – I am looking for elements (c) in the document root, where the id attribute value (note that I am converting it to string – otherwise it’s just an instance of XAttribute) is equal to 80.

The element converted to string will look like this:

<customer id="80">  <name value="Sample Name 3" /></customer>

 

Note, that you cannot use Convert.ToString() instead of (string) to compare the attribute value when executing the query. Converting it to string via the ToString method will not return the value.

I can also build the query to read the values from inside the existing node. What if I want to find the customer with the name equal to “Sample Name”. By slightly modifying the existing query, I will get the needed value:

XElement main = XElement.Load(@"D:\Temporary\customers.xml");IEnumerable<XElement> searched =    from c in main.Elements("customer")    where (string)c.Element("name").Attribute("value") == "Sample Name"    select c;

I can also specify multiple conditions for a query. For example, I need to find the client both with the ID 84 and the name equal to “Sample Name”. Although shown on a very generic (read: obvious) example, it can be easily implemented for more complex data:

XElement main = XElement.Load(@"D:\Temporary\customers.xml");IEnumerable<XElement> searched =    from c in main.Elements("customer")    where (string)c.Attribute("id") == "84"    && (string)c.Element("name").Attribute("value") == "Sample Name"    select c;

It is also possible to have nested queries. I am going to modify my XML file a bit to make it more complex:

<customers>  <customer id="84">    <name value="Sample Name" />    <age value="23" />    <location>      <city value="Los Angeles" />      <state value="CA" />    </location>  </customer>   <customer id="89">    <name value="Sample Name 2" />    <age value="31" />    <location>      <city value="Wichita" />      <state value="KS" />    </location>  </customer>   <customer id="80">    <name value="Sample Name 3" />    <age value="41" />    <location>      <city value="Seattle" />      <state value="WA" />    </location>  </customer></customers>

 

I am going to run a test query, that integrates another query:

XElement main = XElement.Load(@"D:\Temporary\customers.xml");IEnumerable<XElement> searched =    from c in main.Elements("customer")    where (from m in c.Elements("location") where (string)m.Element("city").Attribute("value") == "Los Angeles"    && (string)m.Element("state").Attribute("value") == "CA" select m).Any()    select c;

Here I am selecting the node based on the specified location. Any() is a quantifier operation, that determines whether the any of the returned elements satisfy the condition specified and it returns a Boolean value.

Querying XML elements via LINQ is more reliable when it comes to complex conditions – it is a bit more complicated to check the same node for multiple conditions and sub-node values and attributes with a foreach loop and LINQ not only simplifies the process, but makes it more organized.

MongoDB Atlas is the best way to run MongoDB on AWS — highly secure by default, highly available, and fully elastic. Get started free. Brought to you in partnership with MongoDB.

Topics:
dotnet ,xml ,linq ,data ,c-sharp

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}