Monday, June 23, 2008

XSL Transformations in .NET 2.0

The core XSLT related classes are contained in the System.Xml.Xsl namespace, and are as follows:

XslCompiledTransform - Core class that acts as the XSLT processor in .NET Framework 2.0. Used to transform XML data into other structures such as HTML, text, or another XML.
XsltArgumentList - Allows you to pass a variable number of parameters and extension objects to an XSL style sheet.
XsltCompileException - This exception is thrown by the Load() method when an error occurs in the XSL style sheet.
XsltException - This exception is thrown if an exception occurs during the processing of an XSL style sheet.
Note that the XslTransform class used for XSL transformations in .NET Framework 1.x is now obsolete, and replaced by the new XslCompiledTransform class. In addition to better performance, the XslCompiledTransform also provides better support for the XSLT 1.0 specification. Starting from .NET Framework 2.0, the recommended approach to performing XSL transformations is through the XslCompiledTransform class. Because of the similarity in design to the XslTransform class, you can easily migrate your existing code to utilize the XslCompiledTransform class.

Before looking at the code sample, let us have a brief look at the important methods of the XslCompiledTransform class that will be required.

Load - This method has several overloads, and it provides for loading of an XSL stylesheet into an XslCompiledTransform object from any one of the following resources: a string that specifies the URL, from an XmlReader object, or from an XPathNavigator object, and so on.
Transform - Allows you to transform the XML data into a specified format using the stylesheet that is already loaded (using the Load method).
Implementation
Now that you have had an overview of the XSLT classes and the methods, let us start by looking at a simple XSL transformation example. For the purposes of this article, you will retrieve the data from AdventureWorks database in the form of XML data, and transform it using XSLT to render the data as HTML in the browser.

Simple XSL Transformation
In this example, you will create a simple ASP.NET page that retrieves categories data from the DB as an XML stream and transforms that into HTML so that it can be displayed in the browser. Before looking at the ASP.NET page, let us look at the XSL file named Category.xsl.

Collapse









Simple XSLT Transformation














center










The XSL file basically contains the logic to loop through all the elements contained in the Categories element. The code for the ASP.NET page is as follows:









In the Page_Load event of the Web form, you retrieve the data (in the form of XML) from the ProductSubcategory table, and then apply an external XSLT stylesheet (named Category.xsl) on the XML data, to emit HTML. You then write this HTML directly onto the client browser. This is accomplished by passing in the Response.Output object to the Transform() method. Note that in the above example, the XPathDocument class is used for loading the XML document, because this class is optimized to provide high-performance XML document processing. If you navigate to the page using the browser, you will see the output below.



Passing Parameters to an XSLT Stylesheet
Similar to the way you pass parameters to a method or a function, you can also pass parameters to an XSLT stylesheet. Passing a parameter to a stylesheet gives you the ability to initialize a globally scoped variable, which is defined as any that is a child of the element. The code shown in bold shows the lines of code where the parameter is declared and then used:

Collapse










Passing Parameters to an XSLT Style Sheet

















center










After the declaration of the BackGroundColor parameter, the code then uses the BackGroundColor parameter to specify the background color for the element in the table.


Although the value of BackGroundColor was hard-coded in the declaration using the <> element, ideally it should be passed from the calling ASP.NET page. To accomplish this, you leverage the XsltArgumentList class. Specifically, the AddParam() method of the XsltArgumentList provides this functionality. The XsltArgumentList class is a key class that enables you to create XSLT reusable and maintainable style sheets by providing a mechanism to pass parameters to an XSLT stylesheet.

To the AddParam() method, you supply a qualified name, the namespace URI, and a value. If the parameter value is not a String, Boolean, Number, NodeFragment, or NodeSet, it will be forced to a double or string. The ASP.NET calling page that passes parameters to the stylesheet is shown below:

Collapse
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>


The above code is very similar to the first example except for the difference that this example uses the XsltArgumentList object. Specifically, you create an instance of the XsltArgumentList object, invoke its AddParam() method to add the BackGroundColor parameter, and finally pass the XsltArgumentList as an argument to the Transform() method of the XslCompiledTransform. With all these enhancements in place, pointing the browser to the URL of the Web page results in the following output wherein all the categories records are displayed with the Tan background color:



Invoking Extension Objects from an XSLT Stylesheet
In addition to allowing you to pass parameters, the XsltArgumentList class also provides you with the ability to associate a class with the namespace URI, using which you can call the methods of a class directly from a stylesheet. The object whose methods are invoked from the stylesheet is called an extension object. For the purposes of this example, let us create an extension object named DateTimeConverter to format the ModifiedDate value to the appropriate format. To this end, let us create the DateTimeConverter class with only one method named ToDateTimeFormat() that formats the input date value based on the supplied format string.

using System;

public class DateTimeConverter
{
public DateTimeConverter()
{}

public string ToDateTimeFormat(string data, string format)
{
DateTime date = DateTime.Parse(data);
return date.ToString(format);
}
}
Place the DateTimeConverter class in the App_Code folder so that it can then be easily referred to from the ASP.NET page. To be able to invoke the extension object from the XSLT stylesheet, you need to do the following:

Declare an alias for the extension object namespace at the top of the XSLT file
Invoke the method of the extension object using the alias
Collapse










Invoking extension objects from an XSLT Style Sheet

















center










As you can see, the adjustments made to the stylesheet are minimal. To the xsl:stylesheet element, you add the attribute xmlns:DateTimeConverter="urn:DateTimeConverter". This is done to associate a namespace URI for our extension object. The following line of code creates the association.


Once you have the association between the object and the namespace URI in place, you can then easily invoke the methods of the extension object from the stylesheet as if it is part of the stylesheet.

The following line of code demonstrates this.


In the above line, you invoke the ToDateTimeFormat() method of the DateTimeConverter class, passing to it the ModifiedDate and the desired date format string.

Now that you have had a look at the changes to the style sheet, let us turn our focus to the code required to pass the extension object to the stylesheet so that it can invoke the methods of the extension object.

Collapse
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>
<%@ Import Namespace="System.Xml.XPath" %>
<%@ Import Namespace="System.Web.Configuration" %>


Let us walk through the important lines of the code.

In this line, you create an instance of the BGColor class.

DateTimeConverter converter = new DateTimeConverter();
After you create an instance of the object, the next step would be to add the instantiated object to the XsltArgumentList object.

argsList.AddExtensionObject("urn:DateTimeConverter",converter);
Finally, you pass the instantiated object, along with the rest of the parameters, to the stylesheet, using the following line of code:

transform.Transform(xpathDoc,argsList,Response.Output);
Executing the above code results in the following output:



As you can see from the above output, the ModifiedDate value is appropriately formatted.

Conclusion
In this article, you have seen the following:

How to transform an XML document using an XSLT stylesheet.
How to supply parameters to an XSLT stylesheet using the XsltArgumentList class.
How to invoke methods of an extension object from an XSLT stylesheet.
How to filter a set of nodes using an XPath expression.
Although the application we created was simple in functionality, it should provide a solid foundation for understanding how to create applications using XSLT related classes in the .NET Framework 2.0.

No comments: