posted on Wednesday, July 11, 2007 6:09 PM
by
Girish Borkar
Extending XSLT with Extension Objects in .NET
XSLT 2.0 is good news but .NET 2.0 supports only XSLT 1.0. Even Orcas is not going to support XSLT 2.0.
Microsoft has a good explanation for this decision. They suggest you use XQuery 1.0.
You can read about it
here.Anyway, I needed to do some special transformations (non-trivial string/date formatting and ebcdic encoding) that are
not
supported out of the box in XSLT 1.0. I decided to look for free xslt
extensions and tried exslt and others. After an unsuccessful attempt at
tring to setup and use them, I gave up. Instead, I resorted to doing
the special handling on the C# side, where I am more comfortable. Here
is how you do it.
Using the XSLT extension feature provided by .NET, custom code can be invoked from an XSLT stylesheet.
Steps required to use the Extension Object functionality:
* Write a class with a method that implements the special functionality.
* Create and object of the above class and add an extension object to
the XsltArgumentList class using the AddExtensionObject method.
* Pass this XsltArgumentList object to the XslCompiledTransform.Transform method.
* Add the namespace in the XSL stylesheet to refernce the extension objects from the stylesheet
I am pasting a sample code snippet below which implements ToUpper().
Sample XML File
<?xml version="1.0" encoding="utf-8" ?>
<root>
<node name="node1">Hello World!</node>
</root>
Sample XSLT File
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:stringhelper="urn:StringHelper">
<xsl:output method="text" omit-xml-declaration="yes">
<xsl:template match="/">
<xsl:for-each select="//Node">
<xsl:value-of select="StringHelper:ToUpper(.)">
</xsl:value-of>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output: HELLO WORLD!
Code
namespace XsltTest
{
class Program
{
static void Main(string[] args)
{
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("XSLTFile1.xslt");
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("XMLFile1.xml");
FileInfo fileInfo = new FileInfo(@"output.txt");
using (StreamWriter writer = fileInfo.CreateText())
{
XsltArgumentList xsltArgs = new XsltArgumentList();
xsltArgs.AddExtensionObject("urn:StringHelper", new StringHelper());
transform.Transform(xmlDoc, xsltArgs, writer);
}
}
}
//
// This is the extension class.
// It implements the trivial ToUpper(),
// but certainly can be used for complex operations
//
public class StringHelper
{
public string ToUpper(string str)
{
return str.ToUpper();
}
}
}