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.
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.
<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>
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.
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
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.
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 />"; }
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.