XT's new experimental extensibility mechanism is based on the idea of
filtering fragments of the result tree through an object.
The xsl:filter element specifies a filter. It has attributes that
specify the filtering object in the same way as the HTML 4.0 OBJECT tag.
(The current XT implementation supports only a tiny subset of this:
there must be a classid attribute whose value is a URI starting with
"java:". It also has a limitation that xsl:filter cannot be used inside
xsl:attribute, xsl:pi or xsl:comment.) The content of the xsl:filter
element contains the result tree fragment to be filtered. The
xsl:filter element can also start with xsl:arg elements that specify
parameters to the object. The result of the xsl:filter element is the
filtered result tree fragment.
For example:
<xsl:template match="price">
<xsl:filter classid="java:ConvertPrice">
<xsl:arg name="currency" value="baht">
<xsl:value-of select="."/>
</xsl:filter>
</xsl:template>
Note that xsl:filter elements can be nested. For example, you could
have a filter around a whole document that did Braille contraction, and
then somwhere in the content of the document that there could be a
filter that totalled a list of numbers. The string output by the
totalling filter would be part of the input to the Braille contraction
filter.
In XT's current implementation the Java object must implement an
extension of the SAX DocumentHandler interface:
package com.jclark.xsl.sax;
public interface Filter extends org.xml.sax.DocumentHandler {
void setDocumentHandler(org.xml.sax.DocumentHandler handler);
void setParameter(String name, String value) throws SAXException;
}
I hope to also allow filters to be written using the DOM with an
interface along the lines of:
public interface Transformer {
void transform(DocumentFragment node);
}
One interesting possibility is when the object invokes a script engine
on a script that is passed as an argument (demo/JSFilter illustrates
this with FESI).
I'm also thinking about supporting script directly, using something like
this:
<xsl:script type="text/javascript">
function diddle(fragNode) {
//...
}
</xsl:script>
...
<xsl:template match="foo">
<xsl:filter type="text/javascript" script="diddle(this)"
<xsl:apply-templates/>
</xsl:filter>
</xsl:template>
Please note that all of this is non-standard, and may completely go away
or change depending on how the XSL spec ends up.
James