Geeks With Blogs
Carl Zumbano
The XslTransform class has been deprecated in .NET 2.0 and replaced by the XslCompiledTransform class. The only difference seeems to be better performance and tighter default security settings (embedded scripting is disabled by default). There is an article on MSDN Migrating From the XslTransform Class that details the changes. I have a small sample that uses XSL to sort data in an XML docuemnt. The only change I had to make for 2.0 was replace the XslTransform declaration with XslCompiledTransform. The program reads an Orders XML file, uses an XSL transform to sort the Orders by Id and the items by name.
Figure 1: Orders XML
<?xml version="1.0" encoding="utf-8" ?>
<
orders>
  <
order id="789">
    <
items>
      <
item name="paint" price="30" quantity="2" />
      <
item name="glue" price="2" quantity="10" />
    </
items>
  </
order>
  <
order id="123">
    <
items>
      <
item name="sprockets" price="1" quantity="50" />
      <
item name="cogs" price="20" quantity="5" />
    </
items>
  </
order>
  <
order id="456">
    <
items>
      <
item name="nails" price="2" quantity="100" />
    </
items>
  </
order>
</
orders>
Figure 2: Sorting XSL
<?xml version="1.0" encoding="UTF-8"?>
<
xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<
xsl:output method="xml" indent="yes"/>

<
xsl:template match="orders">
<
orders>
    <
xsl:for-each select="order">
    <
xsl:sort data-type="number" select="@id" />
    <
order>
        <
xsl:attribute name="id">
      <
xsl:value-of select="@id" />
    </
xsl:attribute>
    <
xsl:apply-templates select="items"  />
  </
order>
</
xsl:for-each>
</
orders>
</
xsl:template>

<
xsl:template match="items">
<
xsl:for-each select="item">
<
xsl:sort data-type="text" select="@name" />
  <
item>
    <
xsl:attribute name="name">
      <
xsl:value-of select="@name"/>
    </
xsl:attribute>
    <
xsl:attribute name="price">
      <
xsl:value-of select="@price"/>
    </
xsl:attribute>
    <
xsl:attribute name="quantity">
      <
xsl:value-of select="@quantity"/>
    </
xsl:attribute>      
  </
item>
    </
xsl:for-each>
</
xsl:template>
</
xsl:stylesheet>
The XSL transform is pretty self-explanatory, it uses a for-each with an xsl:sort on the Order and Item nodes. The consoloe applicaiton simply loads the XML and XSL documents and writes the transformed XML to a String Writer.
Figure 3: Console Application
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;

namespace SortXML
{
    
class Program
    {
        
static void Main(string[] args)
        {            
            
XmlTextReader xmlSource = new XmlTextReader("Data.xml");
            
XPathDocument xpathDoc = new XPathDocument(xmlSource);

            
XmlTextReader xslSource = new XmlTextReader("Sort.xsl");
            
XslCompiledTransform xsltDoc = new XslCompiledTransform();

            xsltDoc.Load(xslSource);

            
StringBuilder sb = new StringBuilder();
            
StringWriter sw = new StringWriter(sb);

            xsltDoc.Transform(xpathDoc,
null, sw);
            
            
Console.WriteLine(sb.ToString());

            
Console.WriteLine("Press any key to continue...");
            
Console.ReadLine();
        }
    }
}
Screenshot: Program Output
I ran a few quick tests and for larger documents there was a noticable improvement in execution times using XslCompiledTransform rather than XslTransform.
  Execution Time (ms)
250 nodes 2000 nodes 65536 nodes
XslCompiledTransform.Transform() 38.93 87.59 2,589.35
XslTransform.Transform() 21.11 99.18 3,991.57
Posted on Friday, March 31, 2006 6:04 PM | Back to top


Comments on this post: Moving to XslCompiledTransform

# re: Moving to XslCompiledTransform
Requesting Gravatar...
When doing this in vb, I get "declaration expected" errors when I try to use XslCompiledTransform, even after I declare it. Weird!

******************

Imports System
Imports System.IO
Imports System.Xml
Imports system.xml.Xsl
Imports System.Xml.XPath
Imports System.Web.UI.Page
Imports System.Collections
Imports System.ComponentModel
Imports System.Data
Imports System.Web


Partial Class printItem
Inherits System.Web.UI.Page


Dim xslt As New XslCompiledTransform()
xslt.Load("output.xsl")

' Execute the transform and output the results to a file.
xslt.Transform("books.xml", "books.html")

End Class


******************
Left by Jaybill on Aug 03, 2006 10:52 AM

# re: Moving to XslCompiledTransform
Requesting Gravatar...
I think you're just missing a subroutine, try this:

Partial Class printItem
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim xslt As New XslCompiledTransform()
xslt.Load(Server.MapPath("Books.xsl"))

'Execute the transform and output the results to a file.
xslt.Transform(Server.MapPath("Books.xml"), "c:\output\books.html")
End Sub
End Class

Good Luck,
Carl
Left by Carl on Aug 03, 2006 6:50 PM

# re: Moving to XslCompiledTransform
Requesting Gravatar...
When doing this in vb, I get "declaration expected" errors when I try to use XslCompiledTransform


White space cannot be stripped from input documents that have already been loaded. Provide the input document as an XmlReader instead.
Left by Abel Dama on Nov 26, 2008 11:42 PM

Your comment:
 (will show your gravatar)


Copyright © Carl Zumbano | Powered by: GeeksWithBlogs.net