Although writing Saxon Integrated Extension Functions are pretty clear to me.
I have red:
I'm having extremely hard time finding information how to actually get them to work.
Q: Where to put files, do I have to complie anything, do I have to edit saxon configuration? Basically what do I have to do to get this working besides registering an extension function with the s9api Processor.
TestMain.java - some java file with access to transformation factory
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import net.sf.saxon.TransformerFactoryImpl;
import net.sf.saxon.s9api.ExtensionFunction;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.jaxp.SaxonTransformerFactory;
import location.to.test.java.file.Test;
public class TestMain {
public static void main(String[] args) throws IOException, URISyntaxException, TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
// Grab the handle of Transformer factory and cast it to TransformerFactoryImpl
TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) factory;
// Get the currently used processor
net.sf.saxon.Configuration saxonConfig = tFactoryImpl.getConfiguration();
Processor processor = (Processor) saxonConfig.getProcessor();
// Here extension happens, test comes from class Test -> Test.java
ExtensionFunction test = new Test();
processor.registerExtensionFunction(test);
Source xslt = new StreamSource(new File("test.xsl"));
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File("input.xml"));
transformer.transform(text, new StreamResult(new File("result.xml")));
}
}
Test.java - the actual extension function logic
import net.sf.saxon.s9api.ExtensionFunction;
import net.sf.saxon.s9api.ItemType;
import net.sf.saxon.s9api.OccurrenceIndicator;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.SequenceType;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmValue;
public class Test implements ExtensionFunction {
@Override
public QName getName() {
return new QName("http://some.namespace.com", "test");
}
@Override
public SequenceType getResultType() {
return SequenceType.makeSequenceType(ItemType.STRING, OccurrenceIndicator.ONE);
}
@Override
public net.sf.saxon.s9api.SequenceType[] getArgumentTypes() {
return new SequenceType[] {};
}
@Override
public XdmValue call(XdmValue[] arguments) throws SaxonApiException {
String result = "Saxon is being extended correctly.";
return new XdmAtomicValue(result);
}
}
test.xsl - test xsl. file
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://some.namespace.com">
<xsl:output indent="yes"/>
<xsl:template match="/">
<root>
<xsl:value-of select="ext:test()" />
</root>
</xsl:template>
</xsl:stylesheet>
result.xml - the result of entire process
<?xml version="1.0" encoding="UTF-8"?>
<root>Saxon is being extended correctly.</root>
Please notice that namespace used in .java and .xsl file must be the same, declared in QName
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With