Load and Read XML Files with LINQ to XML in C#: A Guide to Using LINQ Descendants

Next →

LINQ (Language Integrated Query) is a powerful set of features introduced in .NET Framework 3.5 (Visual Studio 2008) that enables developers to perform advanced queries on various data storage types. This includes the ability to read and update XML documents with ease. In this comprehensive guide, we'll explore how to leverage LINQ to XML features to load and read XML data. Through practical examples, you'll learn how to effectively navigate and manipulate XML documents, making the most of LINQ's robust capabilities. Whether you're a seasoned developer or just getting started, this article will provide you with valuable insights into using LINQ for XML data processing.

An XML document has many elements in the form of attributes and Child attributes. To read each attribute, we will need a special method and LINQ provides this method in the form of Descendants().

We will see how we can use the descendants() method in our example to target a "specific" attribute and its child attributes to read data in XML.

Find All Elements in XML using LINQ to XML Features

Before we begin, we need to create an XML document or a file. It’s a library of books. Yes, I have used this document many times in many articles before. Its simple and here you will find the XML file.

Library.xml

You must create a file with the extension “.xml” and name it library. Copy the contents as it is in the file and save the file in the root directory.

To enhance our web page, we need to add a few controls. A button and a label will suffice for this purpose. When the button is clicked, it will trigger an event to load the XML document. The label will then display the values found within the document.

The Markup
<div>
    <p>
        <input id="bt" type="button" value="Extract" runat="server" 
            onserverclick="showXML" />
    </p>
    <p><label id="lblXML" runat="server"></label></p>
</div>
Code Behind (C#)
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using System.Linq;                 // FOR Descendants().
using System.Xml.Linq;             // FOR XDoument, XElement.

public partial class SiteMaster : System.Web.UI.MasterPage
{
    protected void showXML(object sender, EventArgs e)
    {
        lblXML.InnerHtml = "";          // CLEAR THE LABEL.

        // LOAD XML DOCUMENT.
        var xml_Doc = XDocument.Load(Server.MapPath("library.xml"));

        // LOOK FOR A SPECIFIC XML ELEMENT USING "Descendants".
        IEnumerable<XElement> allElements =
            from xEle in xml_Doc.Descendants("List")
            select xEle;

        // NOW, READ AND DISPLAY THE VALUES.
        foreach (XElement result in allElements)
        {
            lblXML.InnerHtml = lblXML.InnerHtml + "<br />" +
                "<b> Book Name: </b>" + result.Element("BookName").Value + "<br />" +
                "<b> Category: </b> " + result.Element("Category").Value + "<br />" +
                "<b> Price: </b>" + result.Element("Price").Value + "<br />";
        }
    }
}

To load an XML document into an object, I am using the XDocument class, which is provided by the System.Xml.Linq namespace. This class offers several useful methods, including the "Load"() method. By using this method, we can create a new XDocument by passing the XML document's path as a parameter.

Note: For Visual Basic, I am not importing the System.Xml.Linq

VB.NET
Option Explicit On

Partial Class Site
    Inherits System.Web.UI.MasterPage

    Protected Sub showXML(ByVal sender As Object, ByVal args As EventArgs)
        lblXML.InnerHtml = ""       ' CLEAR THE LABEL.

        ' LOAD XML DOCUMENT.
        Dim xml_Doc = XDocument.Load(Server.MapPath("library.xml"))

        Dim allElements As IEnumerable(Of XElement)

        ' LOOK FOR A SPECIFIC XML ELEMENT USING "Descendants".
        allElements = _
            From xEle In xml_Doc.Descendants("List") _
            Select xEle

        ' NOW, READ AND DISPLAY THE VALUES.
        For Each result As XElement In allElements
            lblXML.InnerHtml = lblXML.InnerHtml & "<br />" & _
                "<b> Book Name: </b>" & result.Element("BookName").Value & "<br />" & _
                "<b> Category: </b> " & result.Element("Category").Value & "<br />" & _
                "<b> Price: </b>" & result.Element("Price").Value & "<br />"
        Next
    End Sub
End Class

Result

Linq to XML example

Add More Child Elements

Now, this example is very straightforward. The XML document has a root node with an element <List>. Each <List> element has three child elements, such as, <BookName>, <Category> and <Price>.

However, we may add elements to our child elements too. For example, I’ll divide each book into multiple categories. Therefore, the first book in the library may fall under category computers and architecture. The structure will look like this.

The XML

<List>
  <BookName>Computer Architecture</BookName>
  <Category>
    <Cate1>Computer</Cate1>
    <Cate2>Architecture</Cate2>
  </Category>
  <Price>125.60</Price>
</List>

Now, in <Category> node, I have added two more child elements, that is, <Cate1> and <Cate2>. Each has a unique value.

We need to modify a small piece of the code. To show different categories, I am using the Descendants() method again and this time inside the loop. The method will now look for descendant (or child) elements inside the <Category> element. That’s what we want.

C#
foreach (XElement result in allElements)
{
    lblXML.InnerHtml = lblXML.InnerHtml + "<br />" +
        "<b> Book Name: </b>" + result.Element("BookName") + "<br />" +
        "<b> Category: </b> " + result.Element("Category").Descendants("Cate1").ElementAt(0).Value +
            " and " + result.Element("Category").Descendants("Cate2").ElementAt(0).Value + "<br />" + 
        "<b> Price: </b>" + result.Element("Price") + "<br />";
}
Vb.Net
For Each result As XElement In allElements

    lblXML.InnerHtml = lblXML.InnerHtml & "<br />" & _
        "<b> Book Name: </b>" & result.Element("BookName").Value & "<br />" & _
        "<b> Category: </b> " & result.Element("Category").Descendants("Cate1").Value & _
            " and " & result.Element("Category").Descendants("Cate2").Value & "<br />" & _
        "<b> Price: </b>" & result.Element("Price").Value & "<br />"
Next

The output will show two different categories.

Next →