Project

Profile

Help

Bug #4169

Throws System.NotImplementdException when calling extension function indirectly via package

Added by Jiri Dolejsi over 2 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Category:
.NET API
Sprint/Milestone:
-
Start date:
2019-03-15
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.9, trunk
Fix Committed on Branch:
9.9, trunk
Fixed in Maintenance Release:
Platforms:

Description

For demonstration I use sqrt extension function from saxon-resources. In stylesheet I call extension function indirectly by function from package. When I switch off inlining, it ends with System.NotImplemented exception C# .net Framework 4.7

using System;
using Saxon.Api;
using System.IO;
using System.Text;


namespace TestSaxon
{
    class Program
    {
        static Processor processor = new Processor(true);

        static string p =
           @"<xsl:package name='http://www.ctk.cz/math' " +
           @"  xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xs='http://www.w3.org/2001/XMLSchema' version='3.0' " +
           @"  xmlns:math='http://www.ctk.cz/math' " +
           @"  xmlns:demo='http://example.math.co.uk/demo'>" +
           @"  <xsl:function name='math:sqrt' as='xs:double?' visibility='final'>" +
           @"     <xsl:param name='num' as='xs:double?'/>" +
           @"     <xsl:sequence select='demo:sqrt($num)'/>" +
           @"  </xsl:function>" +
           @"</xsl:package>";


        static String s = @"<xsl:transform version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'" +
               @" xmlns:math='http://www.ctk.cz/math' " +
               @" exclude-result-prefixes='math'> " +
               @" <xsl:use-package name='http://www.ctk.cz/math'/>" +
               @" <xsl:template name='xsl:initial-template' > " +
               @" <out " +
               @" sqrt2='{math:sqrt(2.0e0)}' " +
               @" sqrtEmpty='{math:sqrt(())}'> " +
               @" </out> " +
               @" </xsl:template></xsl:transform>";

        static void Main(string[] args)
        {
            processor.RegisterExtensionFunction(new Sqrt());
            processor.SetProperty("http://saxon.sf.net/feature/optimizationLevel", "-f");
            XsltCompiler xsltCompiler = processor.NewXsltCompiler();
            xsltCompiler.XsltLanguageVersion = "3.0";
            var ms = new MemoryStream(Encoding.UTF8.GetBytes(p));
            XsltPackage pp = xsltCompiler.CompilePackage(ms);
            xsltCompiler.ImportPackage(pp);
            XsltExecutable exec = xsltCompiler.Compile(new StringReader(s));
            Xslt30Transformer transf = exec.Load30();
            XdmDestination dest = new XdmDestination();
            transf.CallTemplate(null, dest);
            Console.WriteLine(dest.XdmNode);
    }

 public class Sqrt : ExtensionFunctionDefinition
    {
        public override QName FunctionName
        {
            get
            {
                return new QName("http://example.math.co.uk/demo", "sqrt");
            }
        }

        public override int MinimumNumberOfArguments
        {
            get
            {
                return 1;
            }
        }

        public override int MaximumNumberOfArguments
        {
            get
            {
                return 1;
            }
        }

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

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

        public override bool TrustResultType
        {
            get
            {
                return true;
            }
        }


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

    internal class SqrtCall : ExtensionFunctionCall
    {
        public override IXdmEnumerator<XdmItem> Call(IXdmEnumerator<XdmItem>[] arguments, DynamicContext context)
        {
            Boolean exists = arguments[0].MoveNext();
            if (exists)
            {
                XdmAtomicValue arg = (XdmAtomicValue)arguments[0].Current;
                double val = (double)arg.Value;
                double sqrt = System.Math.Sqrt(val);
                XdmAtomicValue result = new XdmAtomicValue(sqrt);
                return (IXdmEnumerator<XdmItem>)((IXdmEnumerable<XdmItem>)result).GetEnumerator();
            }
            else
            {
                return EmptyEnumerator<XdmItem>.INSTANCE;
            }
        }
    }
}

History

#1 Updated by Michael Kay over 2 years ago

  • Assignee set to O'Neil Delpratt

#2 Updated by O'Neil Delpratt over 2 years ago

  • Category set to .NET API
  • Status changed from New to In Progress

Thanks for reporting the issue. I have managed to reproduce it.

#3 Updated by O'Neil Delpratt over 2 years ago

This is a bug. In the .NET class DotNetSequenceIterator we are not implementing the method materialize.

#4 Updated by O'Neil Delpratt over 2 years ago

  • Status changed from In Progress to Resolved
  • % Done changed from 0 to 100
  • Applies to branch trunk added
  • Fix Committed on Branch 9.9, trunk added

Bug fixed and committed to subversion. We had to also implement the forEachOrFail method.

#5 Updated by O'Neil Delpratt over 2 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 9.9.1.3 added

Bug fix applied to the Saxon 9.9.1.3 maintenance release

Please register to edit this issue

Also available in: Atom PDF