Advanced XSL Transformations With ASP.NET - Passing the buck
(Page 2 of 7 )
One of the interesting features of XSL Transformations is the ability to define input parameters in a style sheet. Then we can assign values to these parameters at run-time and selectively transform the associated XML document.
Consider the following "articles.xml" file:
<?xml version="1.0"?>
<articles>
<article id="110">
<title>XSL Transformations with ASP.NET</title>
<author>Harish R. Kamath</author>
<category>ASP.NET</category>
<abstract>Leverage on the built-in functionality available in ASP.NET to transform your XML documents using XSL Transformations!</abstract>
</article>
<article id="109">
<title>Input Validation in ASP.NET</title>
<author>Harish R. Kamath</author>
<category>ASP.NET</category>
<abstract>Prevent corrupt data from entering into your database - use built-in ASP.NET validation controls in your scripts.</abstract>
</article>
<article id="108">
<title>Master the ASP.NET DataGrid Server Control</title>
<author>Harish R. Kamath</author>
<category>ASP.NET</category>
<abstract>Learn how to use the powerful ASP.NET DataGrid server control to list data from a database table.</abstract>
</article>
</articles>
A few weeks ago, we showed you how to transform this XML file in order to display a listing in the browser. However, wouldn't it be great if we could just select a single article from this list?
This is where the ability to define input parameters in a XSLT style sheet is useful.
The above XML structure defines an attribute called "id" for each <article> element. We can use this "id" attribute to filter the required <article> at run time. This is analogous to the use of a primary key to retrieve a single row from a database table.
Here is an updated version of the earlier "articles.xsl" style sheet:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:param name="id" />
<xsl:template match="articles">
<xsl:apply-templates select="//article[@id=$id]"/>
</xsl:template>
<xsl:template match="article">
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="author"/>
<xsl:apply-templates select="category"/>
<xsl:apply-templates select="abstract"/>
</xsl:template>
<xsl:template match="title">
<H3>Article Title: <xsl:value-of select="." /></H3>
</xsl:template>
<xsl:template match="author">
<H4>Author: <xsl:value-of select="." /></H4>
</xsl:template>
<xsl:template match="category">
<H4>Category: <xsl:value-of select="." /></H4>
</xsl:template>
<xsl:template match="abstract">
<H5>Abstract:</H5>
<xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet>
The major change in this updated version is the introduction of the following code:
<%
// snip
<xsl:param name="id" />
<xsl:template match="articles">
<xsl:apply-templates select="//article[@id=$id]"/>
</xsl:template>
// snip
%>
There are two new XSLT concepts used here. The first concept is the definition of an input parameter (called "id") for the style sheet using the <xsl:param> element, and the second is the use of an XPath expression. While the first concept is pretty self-explanatory, the use of an XPath expression allows us to select a particular node, i.e. a single <article> element from the "articles.xml" file.
So far, so good. But, how do you pass a value to the input parameter in the style sheet?
Frankly, this depends on the XSLT transformer in use. In our case, the XslTransform() object has the required provisions and the following script shows you how:
<%@ Page Language="C#" %> <%@ import Namespace="System.Xml.Xsl" %> <%@ import Namespace="System.Xml.XPath" %> <%@ import Namespace="System.IO" %> <script runat="server">
void Page_Load() {
// path to the XML and XSLT files
string strXsltFile = Server.MapPath("articles.xsl");
string strXmlFile = Server.MapPath("articles.xml");
// create instance of XstTransform object
XslTransform objXslTransform = new XslTransform();
// load the XSLT style sheet
objXslTransform.Load(strXsltFile);
// create an instance of XPathDocument object
XPathDocument objXmlFile = new XPathDocument(strXmlFile);
// Create an instance of XsltArgumentList object
XsltArgumentList objXslInputArgs = new XsltArgumentList();
objXslInputArgs.AddParam("id","","110");
// create an instance of StringWriter object
StringWriter objSWriter = new StringWriter();
// transform the XML file
objXslTransform.Transform(objXmlFile, objXslInputArgs, objSWriter);
// display the output in the browser
output.Text = objSWriter.ToString();
// clean up memory
objXmlFile = null;
objXslTransform = null;
objSWriter = null;
}
</SCRIPT>
<HTML>
<HEAD>
<TITLE>ASPFree.com</TITLE>
<BASEFONT face="Arial" />
</HEAD>
<BODY>
<asp:Label id="output" runat="server"></asp:Label>
</BODY>
</HTML>
Load this script in your browser to view the following output:

Let us skip the mundane details and drill straight down to the snippet that matters:
<%
// snip
// create an instance of XsltArgumentList object
XsltArgumentList objXslInputArgs = new XsltArgumentList();
objXslInputArgs.AddParam("id","","110");
// snip
%>
Time to introduce one more object from the "System.Xml.Xsl" assembly: the XsltArgumentList() object. As the name suggests, it allows us to define a list of name-value pairs that can be sent as an input argument to the style sheet.
Adding a new name-value pair is as simple as invoking the AddParam() method. This method takes three parameters: the name of parameter in the style sheet file, a namespace URI (if any) and finally, the value itself. In our example, we add a parameter with the name "id" and assign a value to it (hard-coded for the moment).
Now, we need to pass this list to the underlying style sheet. Readers with a sharp memory will recall that we always passed a NULL value (for the second parameter) whenever we invoked the Transform() method of the XslTransform() object. The reason was simple: no input parameter defined, no value passed.
This is not true any longer. The following code snippet show us how to pass the objXslInputArgs() object, instantiated above, to the Transform() method -- which, in turn, passes it to the style sheet.
<%
// snip
// transform the XML file
objXslTransform.Transform(objXmlFile, objXslInputArgs, objSWriter);
// snip
%>
The rest of the code is routine stuff. We retrieve the output of the XSL transformation in the form of the objSWriter() object and display the resultant HTML code in the "output" label server control.
Next: Getting Feedback >>
More ASP.NET Articles
More By Harish Kamath