How to design a page & implement Create/Edit/Display data using XML, XQuery and XSLT

Tarun Kumar Chatterjee
 
Net – Technology Specialist
December 6, 2015
 
Rate this article
 
Views
5830

We can create interactive XSLT applications with the help of HTML or ASPX. With ASPX, XSLT is performed on the server side before the resulting HTML document is downloaded to the client. One of the advantages of client-side XSLT is that, once XML and XSLT files are downloaded, the application is relatively safe to server shutdown or network traffic jams.

Let me explain something more like advantages/disadvantages etc. of using XSLT in my next article.

Let see now an implantation to achieve Create/Edit/Display operations by using XML, XQuery and XSLT

First create an ASP.Net Empty web application project and add a XML named as “Employees.xml” within the project

 <?xml version="1.0" encoding="utf-8"?>
 <Employees>
   <Employee>
     <EmployeeID>1</EmployeeID>
     <EmpName>Tarun1 Chatterjee1</EmpName>
     <Department>IT1</Department>
     <PhNo>9111111111</PhNo>
     <Email>tarun1.chatterjee1@gmail.com</Email>
     <Salary>99999</Salary>
   </Employee>
   <Employee>
     <EmployeeID>2</EmployeeID>
     <EmpName>Tarun2 Chatterjee2</EmpName>
     <Department>IT2</Department>
     <PhNo>9222222222</PhNo>
     <Email>tarun2.chatterjee2@gmail.com</Email>
     <Salary>99999</Salary>
   </Employee>
   <Employee>
     <EmployeeID>3</EmployeeID>
     <EmpName>Tarun3 Chatterjee3</EmpName>
     <Department>IT3</Department>
     <PhNo>9333333333</PhNo>
     <Email>tarun3.chatterjee3@gmail.com</Email>
     <Salary>99999</Salary>
   </Employee>
   <Employee>
     <EmployeeID>4</EmployeeID>
     <EmpName>Tarun4 Chatterjee4</EmpName>
     <Department>IT4</Department>
     <PhNo>9444444444</PhNo>
     <Email>tarun4.chatterjee4@gmail.com</Email>
     <Salary>99999</Salary>
   </Employee>
 </Employees>
 

Add below Employees.xslt file within the same project. Most important part is here, within the xslt how we are storing the fields value into the variables and passing those assigned variables value to “OnEdit” function.

 ssing those assigned variables value to “OnEdit” function. 
 <?xml version="1.0" encoding="utf-8"?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
   <?xml-stylesheet href="Employees.xsl" type="text/xsl"?>
   <xsl:output method="html"/>
   <xsl:template match ="/">
     <html>
       <head>        
       </head>
       <body>
         <h2> Employee Details</h2>
         <table border="1">
           <tr bgcolor="aqua">
             <th style="text-align:Left"> EmployeeId</th>
             <th style="text-align:Left"> Employee Name</th>
             <th style="text-align:Left"> Department</th>
             <th style="text-align:Left"> Phone No Name</th>
             <th style="text-align:Left"> Email ID</th>
             <th style="text-align:Left"> Salary</th>
           </tr>
           <xsl:for-each select="Employees/Employee">
             <tr>
               <td>   
                 <xsl:value-of select="EmployeeID"   />
               </td>
               <xsl:variable name="EmployeeID"  select="EmployeeID" />
               <td>                
                 <xsl:value-of select="EmpName"/>             
               </td>
                <xsl:variable name="EmpName" select="EmpName" />
               <td>                
                 <xsl:value-of select="Department"/>              
               </td>
               <xsl:variable name="Department" select="Department" />
               <td>                
                 <xsl:value-of select="PhNo"/>             
               </td>
                <xsl:variable name="PhNo" select="PhNo" />
               <td>                
                 <xsl:value-of select="Email"/>              
               </td>
               <xsl:variable name="Email" select="Email" />
               <td>                
                 <xsl:value-of select="Salary"/>              
               </td>
               <xsl:variable name="Salary" select="Salary" />
               <td>
                 <button id="btnEdit" type="button" onclick="OnEdit('{$EmployeeID}','{$EmpName}','{$Department}','{$PhNo}','{$Email}','{$Salary}' )" > Edit </button>
               </td>
             </tr>
           </xsl:for-each>
         </table>
         <br/>
         <br/>
         <form id ="form" method="post" action="action_page.php">         
         </form>
       </body>
     </html>
   </xsl:template>
 </xsl:stylesheet>
 

Now add XsltTest.aspx page with the following code

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="XsltTest.aspx.cs" Inherits="XsltTest.XsltTest" %>
 
 <!DOCTYPE html>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head runat="server">
     <title></title>
       <script type="text/javascript">
 
           function OnEdit(empID, empName, dept, ph, email, sal) {
               document.getElementById('empid').value = empID;
               document.getElementById('empname').value = empName;
               document.getElementById('empdept').value = dept;
               document.getElementById('empphno').value = ph;
               document.getElementById('empemail').value = email;
               document.getElementById('empsalary').value = sal;
           }
 
         </script>
 </head>
 <body>
     <form id="form1" runat="server">
 
         <div>
             <table>
                 <tr>
                     <td>
                         <asp:HiddenField ID="empid" runat="server"></asp:HiddenField>
                         <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>                       
                         
                     </td>
                     <td>
                         <asp:Button ID="btnSearch" runat="server" Text="Search By Employee Name" OnClick="btnSearch_Click" />
                     </td>
                 
                  <td>
                       <asp:Button ID="btnUpdate" runat="server" Text="Update" onclick="btnUpdate_Click"> </asp:Button>
                       
                  </td>
                     <td>
                         <asp:Button ID="btnAddNew" Text="Add New Record" runat="server" onclick="btnAddNew_Click"> </asp:Button>
                     </td>
              </tr>
             </table>
         </div>
         <br />
     <div>
     
          <table>            
             <tr>
               <td> Name: </td>
               <td>
                 <input type="text" id="empname" runat="server"></input>
               </td>
             </tr>
             <tr>
               <td>Department: </td>
               <td>
                 <input type="text" id="empdept" runat="server"></input>
               </td>
             </tr>
             <tr>
               <td>Phone No: </td>
               <td>
                 <input type="text" id="empphno" runat="server"></input>
               </td>
             </tr>
             <tr>
               <td>Email: </td>
               <td>
                 <input type="text" id="empemail" runat="server"></input>
               </td>
             </tr>
             <tr>
               <td>Salary: </td>
               <td>
                 <input type="text" id="empsalary" runat="server"></input>
               </td>
             </tr>             
              <tr>
                <td></td>
                  <td>
                      <asp:Literal ID="ltlhtmloutput" runat="server" Visible="true"></asp:Literal>
                  </td>
                  
              </tr>
           </table>
 
     </div>
     </form>
 </body>
 </html>
 
 

We can easily keep the OnEdit JS function in XSLT file; it will catch all the fields value properly at row editing. We can also have the “Text”/”Button” fields in XSLT file, but to access the controls from aspx.cs page I am keeping all the fields in aspx page.

In XsltTest.aspx.cs page we will have to copy the following code

 using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Text;
 using System.Web;
 using System.Web.UI;
 using System.Web.UI.WebControls;
 using System.Xml;
 using System.Xml.XPath;
 using System.Xml.Xsl;
 
 namespace XsltTest
 {
     public partial class XsltTest : System.Web.UI.Page
     {
         protected void Page_Load(object sender, EventArgs e)
         {           
 
             if(!IsPostBack)
             {
                 XmlReader reader = XmlReader.Create(Server.MapPath("Employees.xml"));                
                 BindData(reader);
             }
            
         }
         private void BindData(XmlReader reader)
         {
             string strXSLTFile = Server.MapPath("Employees.xslt");
             
 
             // Creating XSLCompiled object    
             XslCompiledTransform objXSLTransform = new XslCompiledTransform();
             objXSLTransform.Load(strXSLTFile);
 
             // Creating StringBuilder object to hold html data and creates TextWriter object to hold data from XslCompiled.Transform method    
             StringBuilder htmlOutput = new StringBuilder();
             TextWriter htmlWriter = new StringWriter(htmlOutput);
 
             // Creating XmlReader object to read XML content    
             //XmlReader reader = XmlReader.Create(strXMLFile);
 
             // Call Transform() method to create html string and write in TextWriter object.    
             objXSLTransform.Transform(reader, null, htmlWriter);
             ltlhtmloutput.Text = htmlOutput.ToString();
 
             // Closing xmlreader object    
             reader.Close();
 
         }
 
         /// <summary>
         /// Search record 
         /// </summary>
         /// <param name="sender">button object</param>
         /// <param name="e">EventArgs object</param>
         protected void btnSearch_Click(object sender, EventArgs e)
         {
             if (txtSearch.Text.Trim() == "")
             {
                 string strXMLFile = Server.MapPath("Employees.xml");
                 XmlReader xReader = XmlReader.Create(strXMLFile);
                 BindData(xReader);
                 return;
             }
             string xpath = String.Format("/Employees/Employee[contains(translate(EmpName,'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '{0}')]", txtSearch.Text.ToLower());
             XmlDocument doc = new XmlDocument();
             doc.Load(Server.MapPath("Employees.xml"));
             XmlElement root = doc.DocumentElement;
             XmlNode node = root.SelectSingleNode(xpath); ;
             XmlNodeList nodeList = root.SelectNodes(xpath);
             string xmlData = string.Empty;
             if (nodeList != null & nodeList.Count > 0)
             {
                 foreach (XmlNode xNode in nodeList)
                 {
                     xmlData += xNode.OuterXml;
                 }
             }
             xmlData = @"<?xml version='1.0' encoding='utf-8'?>" + "<Employees>" + xmlData + "</Employees>";
             // Create the XmlReader object.
             XmlReader reader = ToXmlReader(xmlData);
             BindData(reader);
             
         }
         private XmlReader ToXmlReader(string value)
         {
             var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, IgnoreWhitespace = true, IgnoreComments = true };
             var xmlReader = XmlReader.Create(new StringReader(value), settings);
             xmlReader.Read();
             return xmlReader;
         }
         public int Nodecount()
         {
             string xpath = String.Format("/Employees/Employee");
             XmlDocument doc = new XmlDocument();
             doc.Load(Server.MapPath("Employees.xml"));
             XmlElement root = doc.DocumentElement;
             XmlNode node = root.SelectSingleNode(xpath); ;
             XmlNodeList nodeList = root.SelectNodes(xpath);
             return nodeList.Count;
         }
         /// <summary>
         /// Add record
         /// </summary>
         /// <param name="sender">button object</param>
         /// <param name="e">EventArgs object</param>
         protected void btnAddNew_Click(object sender, EventArgs e)
         {
             int nodeCount = Nodecount();
             nodeCount = nodeCount + 1;
             XmlDocument xmlDoc = new XmlDocument();
             xmlDoc.Load(Server.MapPath("Employees.xml"));
             XmlDocumentFragment docFrag = xmlDoc.CreateDocumentFragment();
             string id = nodeCount.ToString();
             string name = empname.Value;
             string dept = empdept.Value;
             string phno = empphno.Value;
             string email = empemail.Value;
             string salary = empsalary.Value;
             docFrag.InnerXml =  "<Employee><EmployeeID>" + id + "</EmployeeID><EmpName>" + name + "</EmpName><Department>" + dept + "</Department><PhNo>" + phno +
                                 " </PhNo><Email>" + email + "</Email><Salary>" + salary + "</Salary> </Employee>";
             XmlNode childNode = xmlDoc.DocumentElement;
             childNode.InsertAfter(docFrag, childNode.LastChild);
             xmlDoc.Save(Server.MapPath("Employees.xml"));
             nodeCount = nodeCount + 1;
             Response.Write("Records Inserted");
             XmlReader reader = XmlReader.Create(Server.MapPath("Employees.xml"));
             BindData(reader);
         }
 
         /// <summary>
         /// Update record
         /// </summary>
         /// <param name="sender">button object</param>
         /// <param name="e">EventArgs object</param>
         protected void btnUpdate_Click(object sender, EventArgs e)
         {
 
             XmlDocument doc = new XmlDocument();
             doc.Load(Server.MapPath("Employees.xml"));
             XmlElement root = doc.DocumentElement;
             string x = root.FirstChild.FirstChild.InnerText;
             XmlElement firstchild = (XmlElement)root.FirstChild;
             var propcount = firstchild.ChildNodes.Count;
 
             int nodeCount = Nodecount();
           
             List<string> Employees = new List<string>();
             Employees.Add(empname.Value);
             Employees.Add(empdept.Value);
             Employees.Add(empphno.Value);
             Employees.Add(empemail.Value);
             Employees.Add(empsalary.Value);
 
             string[] s = Employees.ToArray();
             
             bool isMatch = false;
             string s1 = empid.Value.ToString();
             for (int i = 0; i < nodeCount; i++)
             {
                 for (int j = 0; j < propcount; j++)
                 {
                     if (propcount == j + 1)
                         break;
                     if (root.ChildNodes[i].ChildNodes[0].InnerText == s1)
                     {
                         root.ChildNodes[i].ChildNodes[j + 1].InnerText = s[j];
                         isMatch = true;
                     }
                 }
                 if (isMatch)
                     break;
 
             }
             doc.Save(Server.MapPath("Employees.xml"));
             XmlReader reader = XmlReader.Create(Server.MapPath("Employees.xml"));
             BindData(reader);
         }
     }
 }
 
 

Here for the Search functionality & NodeCount I am using XQuery to fetch the data from XML.

Now, rebuild the solution and run.

The output will be looking like:

clip_image001

Trying to add a record

clip_image002

Press on “Add New Record” button

clip_image003

Now editing Name and Department of 4th record

clip_image004

After pressing the “Update” button

clip_image006

Now trying to search by a keyword “4” & then press on “Search by Employee Name” button

clip_image008

Hope this article helps you to get a basic idea to implement the XSLT in your project on need basis.

Happy coding

Tarun Kumar Chatterjee

Category : .Net

Author Info

Tarun Kumar Chatterjee
 
Net – Technology Specialist
 
Rate this article
 
Tarun has been working in IT Industry for over 12+ years. He holds a B-tech degree. He is passionate about learning and sharing the tricks and tips in Azure, .Net ...read more
 

Leave a comment