Last updated: 17th February 2025
Discover how to efficiently traverse an XML document using LINQ in ASP.NET. LINQ offers powerful properties to easily navigate through various XML elements. Similar to database queries, you can retrieve values in an XML document by traversing through the next or previous elements (nodes). In this article, I'll show you how to utilize the NextNode and PreviousNode properties to streamline your XML navigation process. Whether you're handling complex data structures or performing simple queries, LINQ's capabilities make it an invaluable tool for ASP.NET developers.I have two button controls on my web page to do the next and previous operations on the XML doc. The button’s click event will call the code behind procedures to execute the navigation. However, first we need an XML doc.
The XML
<?xml version="1.0"?>
<!-- Last edited by https://www.encodedna.com -->
<Library>
<List>
<BookName>Computer Architecture</BookName>
<Category>Computers</Category>
<Price>125.60</Price>
</List>
<List>
<BookName>Advanced Composite Materials</BookName>
<Category>Science</Category>
<Price>172.56</Price>
</List>
<List>
<BookName>ASP.NET 4 Blue Book</BookName>
<Category>Programming</Category>
<Price>56.00</Price>
</List>
<List>
<BookName>Stategies Unplugged</BookName>
<Category>Science</Category>
<Price>99.99</Price>
</List>
</Library>
Get complete XML data here. Library.xml
<body> <div> <div style="width:300px"> <p style="text-align:center;"><label id="lblXML" runat="server"></label></p> <div> <button class="btprevnext" style="float:right;" id="btnext" onserverclick="next_art" runat="server">Next</button> </div> <div> <button class="btprevnext" style="float:left;" id="btprev" onserverclick="previous_art" runat="server">Previous</button> </div> </div> </div> </body>
When the page loads for the first time, I’ll show the first elements value in the "label". In addition, I’ll store the "BookName" value in a ViewState, so I can use it later to find either the next or previous value.
💡What is a ViewState?: In ASP.NET, ViewState is a method that the platform uses to preserve page and control values between postbacks. It enables a web page to retain the user's input and maintain the page's state across requests to the server.
using System; using System.Collections.Generic; using System.Web; using System.Linq; // FOR Descendants(). using System.Xml.Linq; // FOR XDocument, XElement. protected void Page_Load(object sender, System.EventArgs e) { // SHOW THE FIRST ELEMENT'S VALUES. if (!IsPostBack) { lblXML.InnerHtml = ""; // CLEAR THE LABEL. // LOAD XML DOCUMENT. var xml_Doc = XDocument.Load(Server.MapPath("library.xml")); XElement result = (from xFi in xml_Doc.Descendants("List") select xFi).FirstOrDefault(); if ((result != null)) { lblXML.InnerHtml = "<b> Name: </b>" + result.Element("BookName").Value + "<br />" + "<b> Category: </b> " + result.Element("Category").Value + "<br />" + "<b> Price: </b>" + result.Element("Price").Value; ViewState["selectedBook"] = result.Element("BookName").Value; } else { lblXML.InnerHtml = "Found Nothing"; } } } protected void next_art(object sender, EventArgs e) { navigateXML("next"); } protected void previous_art(object sender, EventArgs e) { navigateXML("previous"); } private void navigateXML(string sGo) { // LOAD XML DOCUMENT. var xml_Doc = XDocument.Load(Server.MapPath("library.xml")); string sSelected_Value = ViewState["selectedBook"].ToString(); // Search XML using the selected value. XElement search_result = (from xFi in xml_Doc.Descendants("List") where xFi.Element("BookName").Value.ToUpper() == sSelected_Value.ToUpper() select xFi).FirstOrDefault(); if ((search_result != null)) { XElement node = null; // Navigage xml document using "NextNode" OR "PreviousNode". // However, first we have to cast "NextNode" OR "PrevioueNode" to XElement to get a value. if ((sGo) == "next") { node = (XElement)search_result.NextNode; // NEXT NODE. } else if ((sGo) == "previous") { node = (XElement)search_result.PreviousNode; // PREVIOUS NODE. } // Check if we have reached the last or first node. if ((node != null)) { lblXML.InnerHtml = ""; // Assign value to a viewstate, so we can ue the value later. ViewState["selectedBook"] = node.Element("BookName").Value; IEnumerable<XElement> search_new_value = null; // NOW, GET VALUES FOR THE NEWLY EXTRACTED BOOKNAME. search_new_value = (from xFi in xml_Doc.Descendants("List") where xFi.Element("BookName").Value.ToUpper() == ViewState["selectedBook"].ToString().ToUpper() select xFi); foreach (XElement result in search_new_value) { lblXML.InnerHtml = lblXML.InnerHtml + "<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 />"; } } } else { lblXML.InnerHtml = "Found Nothing"; } }
Option Explicit On Partial Class Site Inherits System.Web.UI.MasterPage Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load If Not IsPostBack Then lblXML.InnerHtml = "" ' CLEAR THE LABEL. ' LOAD XML DOCUMENT. Dim xml_Doc = XDocument.Load(Server.MapPath("library.xml")) Dim result As XElement = _ (From xFi In xml_Doc.Descendants("List") _ Select xFi).FirstOrDefault() If Not result Is Nothing Then lblXML.InnerHtml = _ "<b> Name: </b>" & result.Element("BookName").Value & "<br />" & _ "<b> Category: </b> " & result.Element("Category").Value & "<br />" & _ "<b> Price: </b>" & result.Element("Price").Value ViewState("selectedBook") = result.Element("BookName").Value Else lblXML.InnerHtml = "Found Nothing" End If End If End Sub Protected Sub next_art(ByVal sender As Object, ByVal e As EventArgs) navigateXML("next") End Sub Protected Sub previous_art(ByVal sender As Object, ByVal e As EventArgs) navigateXML("previous") End Sub Private Sub navigateXML(ByVal sGo As String) ' LOAD XML DOCUMENT. Dim xml_Doc = XDocument.Load(Server.MapPath("library.xml")) Dim sSelected_Value As String = Trim(ViewState("selectedBook")) ' SEARCH XML USING THE SELECTED VALUE. Dim search_result As XElement = _ (From xFi In xml_Doc.Descendants("List") _ Where UCase(xFi.Element("BookName").Value) = UCase(sSelected_Value) Select xFi).FirstOrDefault() If Not search_result Is Nothing Then Dim node As XElement = Nothing ' NAVIGATE XML DOCUMENT USING "NextNode" OR "PreviousNode". If (sGo) = "next" Then node = search_result.NextNode ' NEXT NODE. ElseIf (sGo) = "previous" Then node = search_result.PreviousNode ' PREVIOUS NODE. End If If Not node Is Nothing Then ' CHECK IF WE HAVE REACHED THE LAST OR FIRST NODE. lblXML.InnerHtml = "" ' CLEAR THE LABEL FOR NEW VALUES. ViewState("selectedBook") = node.Element("BookName").Value Dim search_new_value As IEnumerable(Of XElement) search_new_value = _ (From xFi In xml_Doc.Descendants("List") _ Where UCase(xFi.Element("BookName").Value) = UCase(ViewState("selectedBook")) Select xFi) For Each result As XElement In search_new_value lblXML.InnerHtml = lblXML.InnerHtml & _ "<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 If Else lblXML.InnerHtml = "Found Nothing" End If End Sub End Class
Property NextNode
Traverse forward through an XML document using the property NextNode. This property will extract and return next node’s values for the selected node. However, if there is no next node, it will return null.
For example, if the select node has this value, <BookName>ASP.NET 4 Blue Book</BookName>, then it will NextNode property will return the immediate next node, which is this value, <BookName>Stategies Unplugged</BookName>. See the XML document above that I have shared.
Property PreviousNode
The PreviousNode property traverses backward through the XML document. It will extract previous node’s value for the selected node.