5,276,406 members and growing! (16,607 online)
Email Password   helpLost your password?
Languages » XML » XSLT     Intermediate

XSL Transformations in .NET 2.0

By Karthik R N

In this article, you will see 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, and more.
C#, XML, XSLT.NET 2.0, Win2K, Windows, .NET, ASP.NET, VS, VS2005, Dev

Posted: 28 Jun 2006
Updated: 28 Jun 2006
Views: 35,143
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
39 votes for this Article.
Popularity: 5.70 Rating: 3.58 out of 5
8 votes, 20.5%
1
1 vote, 2.6%
2
1 vote, 2.6%
3
13 votes, 33.3%
4
16 votes, 41.0%
5

Introduction

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.

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" />
  <xsl:template match="/">
  <HTML>
    <HEAD>
      <TITLE>Simple XSLT Transformation</TITLE>
    </HEAD>
    <BODY>
      <H2>Simple XSLT Transformation</H2>
      <table border="1" cellSpacing="1" cellPadding="1">
        <center>
          <xsl:for-each select="//Categories">
          <!-- Each record on a seperate row -->
            <xsl:element name="tr">
              <xsl:element name="td">
                <xsl:value-of select="ProductSubcategoryID" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:value-of select="Name" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:attribute name="align">center</xsl:attribute>
                <xsl:value-of select="ModifiedDate" />
              </xsl:element>
            </xsl:element>
          </xsl:for-each>
        </center>
      </table>
    </BODY>
  </HTML>
  </xsl:template>
</xsl:stylesheet>

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:

<%@ 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" %>

<script runat="server">
void Page_Load(object sender, System.EventArgs e)
{
  string connString = WebConfigurationManager.ConnectionStrings
    ["adventureWorks"].ConnectionString;
  using (SqlConnection connection = new SqlConnection(connString))
  {
    connection.Open();
    SqlCommand command = new SqlCommand
      ("Select * from Production.ProductSubcategory as Categories " +
      " for xml auto,elements", connection);
    XmlReader reader = command.ExecuteXmlReader();
    XPathDocument xpathDoc = new XPathDocument(reader);
    string xslPath = Server.MapPath("App_Data/Category.xsl");
    XslCompiledTransform transform = new XslCompiledTransform();
    transform.Load(xslPath);
    transform.Transform(xpathDoc, null, Response.Output);
  }
}
</script>

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 <xsl:param> that is a child of the <xsl:stylesheet> element. The code shown in bold shows the lines of code where the parameter is declared and then used:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" />
  <xsl:param name="BackGroundColor" select="Blue" />
  <xsl:template match="/">
  <HTML>
    <HEAD>
      <TITLE>Passing Parameters to an XSLT Style Sheet</TITLE>
    </HEAD>
    <BODY>
      <H2> Passing Parameters to an XSLT Style Sheet</H2>
      <table border="1" cellSpacing="1" cellPadding="1">
        <center>
          <xsl:for-each select="//Categories">
          <!-- Each record on a seperate row -->
            <xsl:element name="tr">
              <xsl:attribute name="bgcolor">
                <xsl:value-of select="$BackGroundColor" />
              </xsl:attribute>
              <xsl:element name="td">
                <xsl:value-of select="ProductSubcategoryID" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:value-of select="Name" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:attribute name="align">center</xsl:attribute>
                <xsl:value-of select="ModifiedDate" />
              </xsl:element>
            </xsl:element>
          </xsl:for-each>
        </center>
      </table>
    </BODY>
  </HTML>
  </xsl:template>
</xsl:stylesheet>

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

<xsl:value-of select="$BackGroundColor" />

Although the value of BackGroundColor was hard-coded in the declaration using the < xsl:param> 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:

<%@ 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" %>

<script runat="server">
void Page_Load(object sender, System.EventArgs e)
{
  string connString = WebConfigurationManager.ConnectionStrings
    ["adventureWorks"].ConnectionString;
  using (SqlConnection connection = new SqlConnection(connString))
  {
    connection.Open();
    SqlCommand command = new SqlCommand
      ("Select * from Production.ProductSubCategory as Categories " +
      " for xml auto,elements", connection);
    XmlReader reader = command.ExecuteXmlReader();
    XPathDocument xpathDoc = new XPathDocument(reader);
    string xslPath = Server.MapPath("App_Data/Category.xsl");
    XslCompiledTransform transform = new XslCompiledTransform();
    transform.Load(xslPath);
    XsltArgumentList argsList = new XsltArgumentList();
    string backGroundColor = "Tan";
    //Add the required parameters to the XsltArgumentList object

    argsList.AddParam("BackGroundColor", "", backGroundColor);
    transform.Transform(xpathDoc, argsList, Response.Output);
  }
}
</script>

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
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:DateTimeConverter="urn:DateTimeConverter">
  <xsl:output method="html" />
  <xsl:param name="BackGroundColor" select="Blue" />
  <xsl:template match="/">
  <HTML>
    <HEAD>
      <TITLE>Invoking extension objects from an XSLT Style Sheet</TITLE>
    </HEAD>
    <BODY>
      <H2>Invoking extension objects from an XSLT Style Sheet</H2>
      <table border="1" cellSpacing="1" cellPadding="1">
        <center>
          <xsl:for-each select="//Categories">
          <!-- Each record on a seperate row -->
            <xsl:element name="tr">
              <xsl:attribute name="bgcolor">
                <xsl:value-of select="$BackGroundColor" />
              </xsl:attribute>
              <xsl:element name="td">
                <xsl:value-of select="ProductSubcategoryID" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:value-of select="Name" />
              </xsl:element>
              <xsl:element name="td">
                <xsl:attribute name="align">center</xsl:attribute>
                <xsl:value-of select="DateTimeConverter:ToDateTimeFormat
                  (ModifiedDate, 'F')" />
              </xsl:element>
            </xsl:element>
          </xsl:for-each>
        </center>
      </table>
    </BODY>
  </HTML>
  </xsl:template>
</xsl:stylesheet>

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.

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     xmlns:DateTimeConverter="urn:DateTimeConverter">

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.

<xsl:value-of select="DateTimeConverter:ToDateTimeFormat(ModifiedDate, 'F')" />

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.

<%@ 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" %>

<script runat="server">
void Page_Load(object sender, System.EventArgs e)
{
  string connString = WebConfigurationManager.ConnectionStrings
    ["adventureWorks"].ConnectionString;
  using (SqlConnection connection = new SqlConnection(connString))
  {
    connection.Open();
    SqlCommand command = new SqlCommand
      ("Select * from Production.ProductSubCategory as Categories " +
      " for xml auto,elements", connection);
    XmlReader reader = command.ExecuteXmlReader();
    XPathDocument xpathDoc = new XPathDocument(reader);
    string xslPath = Server.MapPath("App_Data/Category.xsl");
    XslCompiledTransform transform = new XslCompiledTransform();
    transform.Load(xslPath);
    XsltArgumentList argsList = new XsltArgumentList();
    string backGroundColor = "Tan";
    //Add the required parameters to the XsltArgumentList object

    argsList.AddParam("BackGroundColor", "", backGroundColor);
    //Create and add the extension object to the XsltArgumentList

    DateTimeConverter converter = new DateTimeConverter();
    argsList.AddExtensionObject("urn:DateTimeConverter", converter);
    transform.Transform(xpathDoc, argsList, Response.Output);
  }
}
</script>

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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Karthik R N



Location: India India

Other popular XML articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 13 of 13 (Total in Forum: 13) (Refresh)FirstPrevNext
Subject  Author Date 
Generalworst articlememberMoh.Shafe3i2:41 8 Sep '07  
GeneralVoted 1 for plagarismmembercykophysh392:14 12 Feb '07  
QuestionWho is the real author ?memberRene Langevin4:08 4 Jul '06  
JokeRe: Who is the real author ?memberAbishek Bellamkonda14:49 4 Jul '06  
AnswerRe: Who is the real author ?memberph0sph0ruz5:28 5 Jul '06  
GeneralRe: Who is the real author ? [modified]memberRahulGeek14:46 20 Jul '06  
AnswerRe: Who is the real author ?memberAshley van Gerven22:53 5 Aug '06  
GeneralRe: Who is the real author ?membermuttok4:05 7 Nov '07  
GeneralGreat articlememberProfox Jase22:21 3 Jul '06  
Generalbadmemberkimdubakur23:26 28 Jun '06  
GeneralRe: bad [modified]memberDisruptedSinner22:04 10 Jul '06  
GeneralC# Classes in XSLTmemberMike DiRenzo9:56 28 Jun '06  
GeneralCoolmemberleppie6:01 28 Jun '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 28 Jun 2006
Editor: Smitha Vijayan
Copyright 2006 by Karthik R N
Everything else Copyright © CodeProject, 1999-2008
Web15 | Advertise on the Code Project