Advertisement:

Skystone Software

http://www.SkystoneSoftware.com

.NET Programming

Applying Stylesheets to Xml Documents (VS 2005)
Published: 9/9/2006

Overview
Xml is becoming a pervasive methodology for the storage and dissemination of data in computer science, driven not only by its cross-platform appeal but also by the myriad of accompanying technologies that now exist to extend Xml into something much more than what was originally intended. One of those technologies is Xml Stylesheets (or Xsl Transform), which allows developers to apply style sheets to Xml documents much like Web developers can apply CSS (Cascading Style Sheets) to raw HTML documents. Xsl can be used to format Xml documents (convert data to HTML, for example) or change them to another file format entirely (convert Xml data to comma-delimited, for example).

Prerequisites

This article will cover how to use the .NET 2.0 Framework to apply existing stylesheets to existing Xml documents. Prior knowledge of both Xml and Xsl are assumed. I recommend the following tutorials on Xml and Xsl if you need to brush up:

Xsl in .NET 2.0

The System.Xml namespace in the .NET Framework exists to facilitate manipulation of Xml documents within .NET programs. The System.Xml.Xsl namespace contains objects that enable application of Stylesheets to Xml documents. Significant changes were made to the .NET Framework between versions 1.1 and 2.0, which means that the method for applying stylesheets to documents has changed completely. Specifically, the XslCompiledTransform object was introduced to the 2.0 Framework.

From MSDN:

The XslCompiledTransform class is an XSLT processor that supports the XSLT 1.0 syntax. It is a new implementation and includes performance gains when compared to the obsolete XslTransform class. The structure of the XslCompiledTransform class is very similar to the XslTransform class. The Load method loads and compiles the style sheet, while the Transform method executes the XSLT transform.

Getting Started

To begin, we will start with an XmlDocument object that contains the Xml to which we will apply our transformation.

<?xml version="1.0" encoding="utf-8" ?> 
<Data> 
    <Item ID="1" Name="Item #1" URL="http://www.vbcity.com/" /> 
    <Item ID="2" Name="Item #2" URL="http://www.vbcity.com/" /> 
    <Item ID="3" Name="Item #3" URL="http://www.vbcity.com/" /> 
    <Item ID="4" Name="Item #4" URL="http://www.vbcity.com/" /> 
</Data> 

The stylesheet that will be applied to this data is designed to format is as an HTML document, with the data displayed in a table.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> 
    <xsl: output 
        method="xml" 
        indent="yes" 
        omit-xml-declaration="yes" 
        doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" 
        doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" 
/> 
    <xsl:template match="/"> 
        <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> 
            <head> 
                <title>My Xml Data</title> 
            </head> 
            <body bgcolor="yellow"> 
                <table border="1" width="100%"> 
                    <tr> 
                        <th>ID</th> 
                        <th>Name</th> 
                        <th>URL</th> 
                    </tr> 
                    <xsl:for-each select="//Data/Item"> 
                        <tr> 
                            <td> 
                                <xsl:value-of select="@ID"/> 
                            </td> 
                            <td> 
                                <xsl:value-of select="@Name"/> 
                            </td> 
                            <td> 
                                <xsl:value-of select="@URL"/> 
                            </td> 
                        </tr>                         
                    </xsl:for-each> 
                </table> 
            </body> 
        </html> 
    </xsl:template> 
</xsl:stylesheet> 

In our code the Xml document should be loaded into an XmlDocument object; the Stylesheet into an XslCompiledTransform object:

' load XMl... 
Dim sXml As String = LoadResource("Data.xml") 
Dim clsXmlDocument As New System.Xml.XmlDocument() 
clsXmlDocument.LoadXml(sXml) 
' load stylesheet... 
Dim sStylesheet As String = LoadResource("Transform.xsl") 
Dim clsStream As System.IO.MemoryStream = New System.IO.MemoryStream() 
Dim clsWriter As System.IO.StreamWriter = New System.IO.StreamWriter(clsStream) 
clsWriter.Write(sStylesheet) 
clsWriter.Flush() 
clsStream.Position = 0 
Dim clsReader As System.Xml.XmlReader = New System.Xml.XmlTextReader(clsStream) 
Dim clsStylesheet As System.Xml.Xsl.XslCompiledTransform = New System.Xml.Xsl.XslCompiledTransform() 
clsStylesheet.Load(clsReader) 

NOTE: LoadResource is a custom function that loads the documents from embedded project resources. You can just as easily load the documents from disk.

Combining the Documents

Once the corresponding documents have been loaded into the appropriate objects, combining them is a relatively simple process: the Transform method of the XslCompiledTransform object processes the input Xsl stylesheet and Xml document, writing the results to a stream. In the following code sample, the transformation is made to a MemoryStream and then extracted into a string.

    Private Function ApplyStylesheet(ByVal Document As System.Xml.XmlDocument, ByVal Stylesheet As System.Xml.Xsl.XslCompiledTransform) As String 

        ' apply the transformation to the specified xml... 
        Dim clsStream As System.IO.MemoryStream = New System.IO.MemoryStream() 
        Dim clsTransform As System.Xml.XmlWriter = New System.Xml.XmlTextWriter(clsStream, System.Text.Encoding.ASCII) 
        Stylesheet.Transform(Document, clsTransform) 
        clsStream.Position = 0 

        ' extract content... 
        Dim bValue As Byte() = DirectCast(Array.CreateInstance(GetType(Byte), clsStream.Length), Byte()) 
        clsStream.Read(bValue, 0, Convert.ToInt32(clsStream.Length)) 

        ' release... 
        clsStream.Close() 
        clsStream.Dispose() 
        clsTransform.Close() 
        clsTransform = Nothing 

        ' return... 
        Return System.Text.UTF8Encoding.UTF8.GetString(bValue) 

    End Function 

If the objects "clsStylesheet" and "clsXmlDocument" in the above code samples are passed to this function (assuming they contain the Xml and Xsl samples above), the result will be an (albiet ugly) HTML document displaying the Item nodes in a green HTML table.

Summary

The XmlDocument and XslCompiledStylesheet objects make it quite simple for .NET 2.0 developers to apply Xsl Stylesheets to Xml documents in code, transforming the original data into another format altogether. Throughout the code samples in this FAQ different stream writers and readers are used, which might be confusing to those not used to working with streams. In actuality, the process of applying a stylesheet to an Xml document boils down to the use of the Transform method on the XslCompiledTransform object.




Written by Scott Waletzko for Skystone Software.
Copyright 2005-2007 by Echosoft Design Studios, LLC, All Rights Reserved.