28 Nov
2006

void XSLT Extension Object Functions

Category:UncategorizedTag: :

XSLT Extension objects are a convenient way to call managed code from your XSLT transformations. 
I have most recently found them useful to provide my CompiledTransformation classes
an easy way to calculate relative linking paths between documents for HTML output. 
While this can be done in XSLT alone, it is not for the faint of heart.

This is a drop-dead simple function to write in my managed code assembly:

public string GetRelativePath(string originPath, string targetPath)
{ // implementation here }

And without visiting all of the gory details of adding my object to the XsltArgumentList,
suffice to say that we can invoke our function like this:

<xsl:value-of select=”ec:GetRelativePath(${originPath}, ${targetPath})”/>

This works great and gives me all sorts of non-W3C-compliant warm fuzzies. 
Now here’s the rub; What if you are writing a more complicated XSLT Extension object
than this one? Perhaps your extension object needs initialization?  Although
you should really strive VERY hard to make something like this stateless, sometimes
we just have to call “Uncle”.  Well, since we can’t get access to the constructor
through XSLT we must provide some sort of parameterized Initialization function. 
Something like this:

public void Init(string connectionString)
{ // implementation here }

This seems reasonable.  Now we invoke it from our XSLT.

<xsl:value-of select=”ec:Init(${connectionString})”/>

All XSLT parsers that didn’t crash, take one step forward.  NOT SO FAST, CompiledTransformation
class!  It turns out that when returning void from an extension object function,
void gets translated into something.  I am not sure exactly what, but the transformation
attempts to insert a value into the document output stream.  There may well be
a good reason for this, and if so I would like to understand it, but the best I can
do for now is provide a reasonable work around.

Assign the function return to a variable that you don’t really want, like so:

<xsl:variable name=”$temp” select=”ec:Init(${connectionString})”/>

Your return value gets boxed into the $temp variable where it can do no harm and your
initialization function is allowed to live.  This technique of calling a void
function from XSLT is not unlike teen sex.  Don’t do it, but if you must do it,
be safe about it.

One thought on “void XSLT Extension Object Functions”

Comments are closed.