在内置模板规则中找不到名为{NAME} METHOD()的匹配0参数函数

时间:2016-03-15 10:18:37

标签: java xml xslt sax saxon

我注册了没有参数的ExtensionFunctionDefinition,但是无法调用它 有什么问题以及如何解决这个问题? 看起来功能未注册 这是代码:

撒克逊

     ...<saxon.he.version>9.7.0-3</saxon.he.version>...
        <groupId>net.sf.saxon</groupId>
        <artifactId>Saxon-HE</artifactId>...

异常

Error at char 29 in xsl:value-of/@select on line 23 column 71 
XTDE1425: Cannot find a matching 0-argument function named {http://date.com}getFormattedNow()
in built-in template rule

XSLT

<xsl:stylesheet ...
            xmlns:dateService="http://date.com"
            exclude-result-prefixes="dateService" version="1.0">
...
            <xsl:value-of select="dateService:getFormattedNow()"/>

ExtensionFunctionDefinition

public class DateExtensionFunction extends ExtensionFunctionDefinition {
public StructuredQName getFunctionQName() {
    return new StructuredQName("", "http://date.com", "getFormattedNow");
}

public SequenceType[] getArgumentTypes() {
    return new SequenceType[]{SequenceType.OPTIONAL_STRING};
}

public SequenceType getResultType(SequenceType[] sequenceTypes) {
    return SequenceType.SINGLE_STRING;
}

public boolean trustResultType() {
    return true;
}

public int getMinimumNumberOfArguments() {
    return 0;
}

public int getMaximumNumberOfArguments() {
    return 1;
}

public ExtensionFunctionCall makeCallExpression() {
    return new ExtensionFunctionCall() {

        public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                return new StringValue("TEST");
        }
    };
}
}

变形金刚

    Processor processor = new Processor(false);
    Configuration configuration = new Configuration();
    TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
    processor.registerExtensionFunction(new DateExtensionFunction());
    configuration.setProcessor(processor);
    transformerFactory.setConfiguration(configuration);
    //...newTransformer

3 个答案:

答案 0 :(得分:0)

您的Processor,Configuration和TransformerFactory之间的关系是错误的。

最好将配置视为包含所有重要数据,并将Processor和TransformerFactory视为配置顶部的API胶合代码。

创建处理器时,它会在下面创建自己的配置。同样适用于TransformerFactoryImpl。所以这里有三个Configuration对象,Saxon创建的两个和你创建的对象。扩展功能在配置中注册,该配置支持(s9api)处理器,该处理器与您在JAXP TransformerFactory中使用的处理器没有任何关系。

我建议你使用JAXP或s9api,但要避免混合它们。如果要使用JAXP,请执行:

    TransformerFactoryImpl transformerFactory = new TransformerFactoryImpl();
    Configuration config = transformerFactory.getConfiguration();
    config.registerExtensionFunction(new DateExtensionFunction());

请注意,在Saxon 9.7中,JAXP接口是作为s9api接口顶层的层实现的。

答案 1 :(得分:0)

这是一些有效的代码(在Saxon 9.7 HE下测试)。我不知道你为什么不这样做:请整理一个说明问题的完整程序。

import ....;
public class ExtensionTest extends TestCase {

public class DateExtensionFunction extends ExtensionFunctionDefinition {
    public StructuredQName getFunctionQName() {
        return new StructuredQName("", "http://date.com", "getFormattedNow");
    }

    public net.sf.saxon.value.SequenceType[] getArgumentTypes() {
        return new net.sf.saxon.value.SequenceType[]{net.sf.saxon.value.SequenceType.OPTIONAL_STRING};
    }

    public net.sf.saxon.value.SequenceType getResultType(net.sf.saxon.value.SequenceType[] sequenceTypes) {
        return net.sf.saxon.value.SequenceType.SINGLE_STRING;
    }

    public boolean trustResultType() {
        return true;
    }

    public int getMinimumNumberOfArguments() {
        return 0;
    }

    public int getMaximumNumberOfArguments() {
        return 1;
    }

    public ExtensionFunctionCall makeCallExpression() {
        return new ExtensionFunctionCall() {

            public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
                return new StringValue("TEST");
            }
        };
    }
}

public void testIntrinsicExtension() {
    try {
        TransformerFactoryImpl factory = new TransformerFactoryImpl();
        factory.getConfiguration().registerExtensionFunction(new DateExtensionFunction());
        String xsl = "<e xsl:version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " +
                "result='{Q{http://date.com}getFormattedNow()}'/>";
        Templates t = factory.newTemplates(new StreamSource(new StringReader(xsl)));
        StringWriter sw = new StringWriter();
        t.newTransformer().transform(new StreamSource(new StringReader("<a/>")), new StreamResult(sw));
        System.err.println(sw.toString());
    } catch (TransformerConfigurationException tce) {
        tce.printStackTrace();
        fail();
    } catch (TransformerException e) {
        e.printStackTrace();
        fail();
    }
    }
}

输出结果为:

<?xml version="1.0" encoding="UTF-8"?><e result="TEST"/>

答案 2 :(得分:0)

解决方案(仅适用于Saxon 9.4):

@Override
public ExtensionFunctionCall makeCallExpression() {
    return new ExtensionFunctionCall() {
        @Override
        @SuppressWarnings("unchecked")
        public SequenceIterator call(SequenceIterator[] arguments, XPathContext context) throws XPathException {
            return SingletonIterator.makeIterator(StringValue.makeStringValue("TEST"));
        }
    };
}