Load and Read XML Document using LINQ to XML in C# Using LINQ Descendants

Next →

LINQ or Language Integrated Query, as you know is set of features introduced first with .Net framework 3.5 (Visual Studio 2008), which provides powerful queries (language) to read and update literally any kind of data storage. LINQ provides necessary classes, methods and properties to read and update XML documents too. Here in this article, I am going to show you, with small examples, on how to load and read XML data using LINQ to XML features.

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.

Here’s another article, which you don’t want to miss.

Extract and Read Data from an XML file using JQuery and Ajax

We need couple of controls on our web page. A button and label controls each will be enough. The button’s click event will load the XML and the label will display the values that it finds in the document.

The Markup
<div style="font:13px Verdana;">
    <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 the XML document in an Object, I am using the “XDocument” Class. Its provided to us with the “System.Xml.Linq” namespace. The class has many useful methods, and one of it is the “load()” method. Using this method, we will create a new XDocument by providing the method a value (parameter) in the form of an XML document and paths. However, for Visual Basic, I am not importing the namespace, I just mentioned above.

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 →