I have a few Saxon/XSLT extension functions that I created through the simple interface that I register like this:
Processor proc = new Processor(false);
proc.registerExtensionFunction(myExtensionFunctionInstance);
Now I want to use that with BaseX, but I see that BaseX instantiates its own Processor instance through JAXP APIs:
// Somewhere inside basex's XSLT transformer instantiation (see link above).
final TransformerFactory tf = TransformerFactory.newInstance();
So it seems I need to find a way to change the factory that BaseX uses such that I can register my functions.
If I get it right I need to create my own factory implementation. Adapted from Saxon's net.sf.saxon.TransformerFactoryImpl:
package my.package;
public class MyOwnTrasnformerFactory extends SaxonTransformerFactory {
public TransformerFactoryImpl() {
super();
ExtensionFunction myFunction = new MyExtFunction(...);
this.processor.registerExtensionFunction(myFunction);
}
public TransformerFactoryImpl(Configuration config) {
super(config);
ExtensionFunction myFunction = new MyExtFunction(...);
this.processor.registerExtensionFunction(myFunction);
}
}
And then I could do:
System.setProperty(
"javax.xml.transform.TransformerFactory",
"my.package.MyOwnTrasnformerFactory");
- Doe this seem like a correct approach?
- Is there's an alternative way to create a single processor instance for the lifetime of my program without creating my custom factory? I'm using Clojure and creating Java classes (genclass) is a bit less convenient and less dynamic.
I ended up implementing the solution described on my question... here's a full gist:
https://gist.github.com/EmmanuelOga/018ece8b4776636ce1ab3f73e215ce75
The relevant parts:
That defines the Java class
rainbowfish.XsltFactoryusing clojure. Since it uses gen-class, it needs to be compiled by callingcompile('rainbowfish.xslt-factory)or by asking lein to compile it, etc.Now that we have a class that configures the XSLT processor, we need to inform BaseX that it should use it. BaseX reads the JAXP configuration for this. The configuration can be set like this:
... this should be called before creating an instance of the BaseX server. See the gist for more details!