Martynas Jusevičius
Martynas Jusevičius

Reputation: 612

How to return document node from Saxon's extension function?

I'm looking at Integrated extension functions in Saxon-HE 10 (Java).

I need the function to return a document-node()? which is constructed from StreamSource.

Answer to a similar question mentions this code:

context.getConfiguration().buildDocument()

However context is not passed to ExtensionFunction, only XdmValue[] arguments.

ExtensionFunctionDefinition does accept XPathContext context, but it looks like getConfiguration().buildDocument() is not present in 10.

Instead, there is context.getConfiguration().buildDocumentTree(Source source), but I don't know how to convert TreeInfo it returns to Sequence required by the interface signature.

Upvotes: 0

Views: 523

Answers (1)

Michael Kay
Michael Kay

Reputation: 163655

The "simple interface" (s9api.ExtensionFunction) does not allow an XPathContext object to be passed in. However, for this purpose you don't need the full XPath dynamic context; you only need access to the configuration object. In fact you can do everything at the s9api level without diving into Saxon internals:

    final Processor proc = new Processor();
    ExtensionFunction ef = new ExtensionFunction() {
          ...
          public XdmValue call(XdmValue[] arguments) throws SaxonApiException {
              Source source = ...;
              return proc.newDocumentBuilder().build(source);           
          }
      };    
    proc.registerExtensionFunction(ef);

If you do need more context information than this, for example if you need access to the static base URI of the expression from which your extension function is called, then you need to use the "full interface" with separate ExtensionFunctionDefinition and ExtensionFunctionCall objects.

You will then need to use lower-level Saxon interfaces such as Sequence and NodeInfo. Configuration.buildDocumentTree() returns a TreeInfo, which has a getRootNode() method returning a NodeInfo. NodeInfo implements Item which implements Sequence, so you can return the NodeInfo from your ExtensionFunctionCall.call() method.

Upvotes: 3

Related Questions