我注册了没有参数的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
答案 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"));
}
};
}