0
votes

I am trying to add an extension function, but is failing with :

Caused by: net.sf.saxon.trans.XPathException: Unknown system function follow()
    at net.sf.saxon.expr.parser.XPathParser.grumble(XPathParser.java:282)

I see (in debug) that function registered with the integrated library. I was expecting saxon to look for the function in the integrated library but it is searching in system functions and throwing error. What is causing this function to be represented as a system function. I am using the following :

<dependency>
   <groupId>net.sf.saxon</groupId>
   <artifactId>Saxon-HE</artifactId>
   <version>9.7.0-14</version>
</dependency>

Thank you

my code is

import net.sf.saxon.expr.XPathContext;
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.s9api.Processor;
import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XPathExecutable;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.SequenceType;

public class FollowTest {
    public static void main(String[] args) throws Exception {
        new FollowTest().test();
    }

    private void test () throws Exception {
        Processor proc = new Processor(false);
        proc.registerExtensionFunction(new Follow());
        XPathCompiler xx = proc.newXPathCompiler();
        XPathExecutable x = xx.compile("follow(/a/b/c)/type='xyz'");
    }

    public class Follow extends ExtensionFunctionDefinition {

        @Override
        public StructuredQName getFunctionQName() {
            return new StructuredQName("", "http://example.com/saxon-extension", "follow");
        }

        @Override
        public int getMinimumNumberOfArguments() {
            return 1;
        }

        @Override
        public int getMaximumNumberOfArguments() {
            return 1;
        }

        @Override
        public SequenceType[] getArgumentTypes() {
            return new net.sf.saxon.value.SequenceType[] {SequenceType.SINGLE_STRING,};
        }

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

        @Override
        public boolean trustResultType() {
            return true;
        }

        @Override
        public boolean dependsOnFocus() {
            return false;
        }

        @Override
        public boolean hasSideEffects() {
            return false;
        }

        @Override
        public ExtensionFunctionCall makeCallExpression() {
            return null;
        }
        private class followCall extends ExtensionFunctionCall {
            @Override
            public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                return null;
            }
        }
    }
}
1
is it due to the prefix "" ? I tried with a new ExtensionFunction() {} and declaring a non empty prefix and it worked. - user19937
Yes, I suspect so. With no prefix, it's probably treating it as being in the default namespace for functions, which is the fn namespace. - Michael Kay

1 Answers

1
votes

In the XPath expression you have written

follow(/a/b/c)

A function name with no namespace prefix is assumed to be in the default namespace for functions, which by default is the system function namespace http://www.w3.org/2005/xpath-functions. You need to use a prefix that's bound to the URI appearing in the extension function definition, namely http://example.com/saxon-extension