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:
Trying to add a record
Press on “Add New Record” button
Now editing Name and Department of 4th record
After pressing the “Update” button
Now trying to search by a keyword “4” & then press on “Search by Employee Name” button
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
Leave a comment