Skip to content

Instantly share code, notes, and snippets.

@robvalk
Created October 5, 2015 01:17
Show Gist options
  • Save robvalk/d1f813f3a92a25bf4643 to your computer and use it in GitHub Desktop.
Save robvalk/d1f813f3a92a25bf4643 to your computer and use it in GitHub Desktop.
XSLT Extension Functions
com.sample.xslt.RandomNumberFunction
package com.sample.xslt;
import java.util.Random;
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;
/** Saxon Extension Function for generating random numbers (similar to the old exslt functions) */
public class RandomNumberFunction implements ExtensionFunction {
private final Random rng = new Random();
@Override
public QName getName() {
return new QName("http://sample.com/xslt", "random");
}
@Override
public SequenceType getResultType() {
return SequenceType.makeSequenceType(ItemType.FLOAT, OccurrenceIndicator.ONE);
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[0];
}
@Override
public XdmValue call(XdmValue[] paramArrayOfXdmValue)
throws SaxonApiException {
return new XdmAtomicValue(rng.nextFloat());
}
}
package com.sample.xslt;
import java.lang.reflect.Field;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.saxon.Configuration;
import net.sf.saxon.jaxp.SaxonTransformerFactory;
import net.sf.saxon.s9api.ExtensionFunction;
import net.sf.saxon.s9api.Processor;
/**
* Extension to the normal Saxon HE JAXP {@link javax.xml.transform.TransformerFactory} that discovers and
* registers ExtensionFunctions via the Java {@link ServiceLoader} framework.
*
*/
public class TransformerFactory extends SaxonTransformerFactory {
private static final Logger log = LoggerFactory
.getLogger(TransformerFactory.class);
public TransformerFactory() {
super();
registerExtensionFunctions();
}
public TransformerFactory(Configuration config) {
super(config);
registerExtensionFunctions();
}
private void registerExtensionFunctions() {
Processor processor;
try {
Field processorField = SaxonTransformerFactory.class
.getDeclaredField("processor");
processorField.setAccessible(true);
processor = (Processor) processorField.get(this);
ServiceLoader<ExtensionFunction> extensionFunctions = ServiceLoader
.load(ExtensionFunction.class, Thread.currentThread()
.getContextClassLoader());
for (ExtensionFunction extensionFunction : extensionFunctions) {
log.info("Registering Saxon extension function {}",
extensionFunction.getName());
try {
processor.registerExtensionFunction(extensionFunction);
} catch (RuntimeException e) {
log.warn("Unable to register Saxon extension function "
+ extensionFunction.getName(), e);
}
}
} catch (NoSuchFieldException | SecurityException
| IllegalArgumentException | IllegalAccessException e) {
log.error("Unable to access Saxon Processer object", e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment