0

I have tried upgrading from SaxonCS 11 to 12 after my ExtensionFunctions are no longer called I get the following exception when I try to compile my xslt.

Saxon.Hej.trans.XPathException: 'Cannot find a 2-argument function named Q{urn:rhea/xpath}get-svgid()'

In SaxonCS 11 everthing worked fine. I was not able to find any information regarding this breaking change in the following documentation

Change history Saxon 11 to 12

My ExtensionFunctionDefinition looks like this.

public class GetSVGID : ExtensionFunctionDefinition
{
    public override QName FunctionName => new QName("urn:rhea/xpath", "get-svgid");

    public override int MinimumNumberOfArguments => 1;

    public override int MaximumNumberOfArguments => 2;

    public override XdmSequenceType[] ArgumentTypes =>
        new[]
        {
            new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?'),
            new XdmSequenceType(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?')
        };

    public override XdmSequenceType ResultType(XdmSequenceType[] ArgumentTypes)
    {
        return new(XdmAtomicType.BuiltInAtomicType(QName.XS_STRING), '?');
    }

    public override bool TrustResultType => true;

    public override ExtensionFunctionCall MakeFunctionCall()
    {
        return new GetSVGIDCall();
    }
}

Is this a known problem. What is required to migrate this code?

using SaxonApi = Saxon.Api;
var spro = new SaxonProcessor(); 
XsltCompiler compiler = spro.Processor.NewXsltCompiler();
compiler.ErrorReporter = error => spro.ErrorList.Add(error);
spro.Processor.RegisterExtensionFunction(new GetSVGID()); 
spro.Executable = compiler.Compile(new Uri(xsltRootPath))

Wrapper Class:

public class SaxonProcessor
{
    public List<SaxonApi.Error> ErrorList = new();
    public SaxonApi.Processor Processor = new SaxonApi.Processor(true);
    public DocumentBuilder DocBuilder;
    public XsltExecutable Executable;
    public bool First;

}

XSLT Part

    <xsl:template name="rhea:get-svgid">
    <xsl:param name="fname" />
    <xsl:param name="fid" />
    <xsl:param name="fidraw" />
    <xsl:choose>
      <xsl:when test="$CBmode = 'CB'">
        <xsl:value-of select="ext:get-svgid($DocIndex, $fname)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>CB:</xsl:text>
        <xsl:value-of select="$fid"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>



   <xsl:variable name="rheaMediaID">
        <xsl:call-template name="rhea:get-svgid">
            <xsl:with-param name="fname">
                <xsl:value-of select="@boardno | @infoEntityIdent"/>
            </xsl:with-param>
            <xsl:with-param name="fid">
                <xsl:value-of select="$figureID"/>
            </xsl:with-param>
            <xsl:with-param name="fidraw">
                <xsl:value-of select="$figureIDraw"/>
            </xsl:with-param>
        </xsl:call-template>
    </xsl:variable>
Kingpin
  • 1,067
  • 2
  • 14
  • 34
  • Also, consider to add all the details as to which Saxon release exactly you are running? Is that SaxonCS 12.3? And it seems SaxonProcessor is your own wrapper class, show all the details of how it is set up and how it implements e.g. `spro.RegisterExtensionFunction`. – Martin Honnen Aug 16 '23 at 11:02
  • You are correct. I added the code of the wrapper. RegisterExtensionFunction is called directly on SaxonApi.Processor. I fixed this in the example code – Kingpin Aug 16 '23 at 11:08
  • I am struggling to reproduce the issue with the details given so far, even when assuming `SaxonApi` is actually `Saxon.Api`. Consider to add minimal but complete code samples of XSLT and C# (and XML if needed) to allow others to reproduce the issue. Is there any chance you are creating sever SaxonProcessors but are not registering the extension function on all of them? – Martin Honnen Aug 16 '23 at 12:07
  • Perhaps it is really better to open an issue at https://saxonica.plan.io/projects/saxon/issues as there you can attach complete files or projects so that Saxonica can reproduce the problem. From the snippets posted above it is hard to construct a complete test case. – Martin Honnen Aug 16 '23 at 13:05
  • Did you manage to resolve this or to create some minimal but complete repro so that it can be reproduced? – Martin Honnen Aug 18 '23 at 07:30
  • We were not able to resolve this yet. We created a minimal repo to reproduce this problem. But in this repo the problem did not occur suggesting this is not a general SaxonCS problem. At the moment we are still investigating what the difference to the production code is. – Kingpin Aug 24 '23 at 08:31

1 Answers1

1

I'm not aware of any breaking change in this area, and the unit tests are all running fine, but the devil is always in the detail. The detail in this case is probably about how you are running the query/transformation and how you are registering your extension function. The error message suggests that it's nothing to do with the way the extension function is written, and everything to do with the way it is registered.

You haven't actually said where you are calling the function from (XSLT, XQuery, XPath) and it makes a difference because the function libraries are set up differently in each case.

You're welcome to raise issues like this on the support forum at saxonica.plan.io.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Thanks for your Feedback. I updated the question. Showing how we are using the SaxonProcessor – Kingpin Aug 16 '23 at 10:58
  • I don't know if this will fix it, but it seems in my test cases we register the ExtensionFunctionDefinition before we create the XsltCompiler. – Michael Kay Aug 16 '23 at 15:05
  • No, I don't think that's it. I've just run a test where the extension function is registered after creating the XsltCompiler and before calling Compile(), and it works fine. – Michael Kay Aug 16 '23 at 15:11
  • As @MartinHonnen suggests, I think we're going to need a repro for this one. Please try to cut it down to a minimal but complete and self-contained demonstration of the problem. – Michael Kay Aug 16 '23 at 15:15