XSLT with Optional Extension Object
by Warlock on Dec.08, 2009, under .NET, C#, xml
Extension objects provide a convenient way to allow an XSL transform to interact with the outside world. They can also be used to offload computations that are difficult to express in XSL.
Recently, I ran into a scenario where I wanted to write an XSLT that would use an extension object to record some additional information about intermediate steps of the transform. The extension object was not required, however, and I wanted to leave it up to the user of the XSLT as to if they wanted to use the extension object.
The question then became how to conditionally execute calls to the extension object. Suppose you have the following extension object defined in C#:
public class FooExtensionObject
{
private List<string> recordedValues = new List<string>();
public void RecordValue(string val)
{
recordedValues.Add(val);
}
}
Now suppose this extension object is used in the following XSLT:
<xsl:transform
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foo="urn:FooExObj">
<template match="/">
...
<xsl:value-of select="foo:RecordValue(@bar)"/>
...
</template>
</transform>
The extension object is supplied to the XSLT through the arguments:
XslTransform transform = new XslTransform();
transform.Load("SomeFile.xsl");
XsltArgumentList args = new XsltArgumentList();
FooExtensionObject aFoo = new FooExtensionObject();
args.AddExtensionObject("urn:FooExObj", aFoo);
XmlTextWriter myWriter = new XmlTextWriter("output.xml", null);
transform.Transform(xpathDoc, args, myWriter);
In the case where the extension object is not supplied, however, this XSLT will cause an error. To correct this issue, you can use the function-available function. Change the transform as follows:
...
<xsl:if test="function-available('foo:RecordValue')">
<xsl:value-of select="foo:RecordValue(@bar)"/>
</xsl:if>
...
The conditional statement blocks out the use of the extension object when it does not exist. Unfortunately, you must do this where ever you wish to use the extension object.