1
votes

I'm using Saxon HE's XPathCompiler class in VB .NET to run XPath queries against an XML file, and then processing the results. I also have an XSL with user-defined functions. Is there a way I can reference these user-defined functions in my XPath queries? I'm successfully referencing them from other XSLs, but unsure how to do it when I'm just executing XPath queries on their own from a Saxon XPathCompiler object.

Basically, I'm hoping there's some way in the following code that I can point at my DocOpsFunctions.xsl stylesheet and access the functions defined there.

Code:

    Dim myProcessor As New Saxon.Api.Processor
    Dim myCompiler As XPathCompiler = myProcessor.NewXPathCompiler()
    myCompiler.XPathLanguageVersion = "3.1"
    Dim myDocBuilder As DocumentBuilder = myProcessor.NewDocumentBuilder
    Dim myDoc As XdmNode = myDocBuilder.Build(New Uri("input.xml"))
    Dim myResults As XdmValue
    myResults = myCompiler.Evaluate("dof:lefttrim('ISTeams/Team'", myDoc) 

DocOpsFunctions.xsl:

<xsl:transform version="3.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dof="http://docops.com">
    <xsl:function name="dof:lefttrim" as="xs:string">
        <xsl:param name="text"/>
        <xsl:value-of select="replace($text, '^\s+', '')"/>
      </xsl:function>
</xsl:transform>

Input.xml:

<ISTeams>
<Team>Team1   </Team1>
<Team>Team2   </Team2>
</ISTeams>

I'm aware of the ability to define extension functions using the ExtensionFunction interface, but am hoping to find a way to do this more dynamically, so that new functions can be implemented in the stylesheet instead of in the code.

1

1 Answers

1
votes

Make sure you declare the function as public with visiblity="public", then you can use fn:transform (https://www.w3.org/TR/xpath-functions/#func-transform) in XPath 3.1:

transform(map { 
 'stylesheet-location' : 'DocOpsFunctions.xsl', 
 'cache' : true(), 
 'delivery-format' : 'raw', 
 'initial-function' : QName('http://docops.com', 
 'lefttrim'), 
 'function-params' : ['  foo']
})?output

In the Java API you should be able to use http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XPathCompiler.html#addXsltFunctionLibrary-net.sf.saxon.s9api.XsltPackage- to expose the functions in an XSLT package/stylesheet to XPath.

In the .NET 10.2 API you should be able to use http://www.saxonica.com/html/documentation/dotnetdoc/Saxon/Api/XPathCompiler.html#AddXsltFunctionLibrary(XsltPackage) to do the same in .NET, namely expose a function library written in XSLT to XPath.