1

I have following simple XSLT example:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fn="http://www.w3.org/2005/xpath-functions"
                xmlns:eg="http://example.com/saxon-extension"
                xmlns:eks="ekstern"
                xmlns:dmp="http://arealinformation.miljoeportal.dk/gis/services/distribution/MapServer/WFSServer"
                exclude-result-prefixes="eg">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:template match="/">
        <xsl:copy>
            <xsl:sequence select="eg:shift-left(1,2)"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

and I have this basic "ShiftLeft" class which I took from a Saxon example: https://www.saxonica.com/html/documentation/extensibility/integratedfunctions/ext-full-J.html

package diadem.base.plugin.helpers;

import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.IntegerValue;
import net.sf.saxon.value.Int64Value;

public class ShiftLeft extends ExtensionFunctionDefinition {
    @Override
    public StructuredQName getFunctionQName() {
        return new StructuredQName("eg", "http://example.com/saxon-extension", "shift-left");
    }

    @Override
    public SequenceType[] getArgumentTypes() {
        return new SequenceType[]{SequenceType.SINGLE_INTEGER, SequenceType.SINGLE_INTEGER};
    }

    @Override
    public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
        return SequenceType.SINGLE_INTEGER;
    }

    @Override
    public ExtensionFunctionCall makeCallExpression() {
        return new ExtensionFunctionCall() {
            @Override
            public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                long v0 = ((IntegerValue)arguments[0]).longValue();
                long v1 = ((IntegerValue)arguments[1]).longValue();
                long result = v0<<v1;
                return Int64Value.makeIntegerValue(result);
            }
        };
    }
}

I am for some reason facing following errormessage in XSLT:

Static error in {eg:shift-left(1,2)} in expression in xsl:sequence/@select on line 12 column 56 of conflictsTestTransform.xslt:
  XPST0017: Cannot find a 2-argument function named Q{http://example.com/saxon-extension}shift-left()

I don't actually know why it cannot invoke the "Call"-method in the Java extension function. The code I am using for transformation:

 private static Document transform(Document inputDoc, File xsltFile) throws XSLTransformException {
        JDOMSource source = new JDOMSource(inputDoc, null)
        JDOMResult result = new JDOMResult()
        try {
            TransformerFactory tFactory = TransformerFactory.newInstance("com.saxonica.config.EnterpriseTransformerFactory", null)
            tFactory.setURIResolver(new XsltUriResolver())
            if(tFactory instanceof TransformerFactoryImpl) {
                TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) tFactory;
                Configuration saxonConfig = tFactoryImpl.getConfiguration();
                saxonConfig.registerExtensionFunction(new ShiftLeft());
            }

            Templates templates = TransformerFactory.newInstance("com.saxonica.config.EnterpriseTransformerFactory", null).newTemplates(new StreamSource(xsltFile))
            Transformer transformer = templates.newTransformer()
            result.setFactory(null)  // null ok
            try {
                transformer.transform(source, result)
                return result.getDocument()
            }
            catch (TransformerException e) {
                throw new XSLTransformException("Could not perform transformation", e)
            }
        } catch (TransformerConfigurationException tce) {
            // Error generated by the parser
            // log.warn("Transformer Factory error", tce)
        } catch (SAXException sxe) {
            // Error generated by this application
            // (or a parser-initialization error)
            // log.warn("SAXException", sxe)
        } catch (ParserConfigurationException pce) {
            // Parser with specified options can't be built
            // log.warn("Parser build error", pce)
        } catch (IOException ioe) {
            // I/O error
            // log.warn("IO error", ioe)
        }

        return null
    }
1
  • Can't you simply use Templates templates = tFactory.newTemplates instead of Templates templates = TransformerFactory.newInstance("com.saxonica.config.EnterpriseTransformerFactory", null).newTemplates? Commented Jul 24, 2019 at 18:32

1 Answer 1

3

You have two TransformerFactories, and two Saxon Configurations; you have registered the extension function with one of them, and you are trying to use it in the other.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.