问题描述
我正在尝试从Tomcat v8.0服务器上的XML文件运行XSLT 2.0转换。 但是,我只能成功将其作为XSLT1运行。
org.apache.xml.utils.WrappedRuntimeException:java.lang.NoSuchMethodException:对于扩展功能,找不到方法org.apache.xml.utils.NodeVector.root([ExpressionContext,])。
我正在使用Saxon,这是pom声明:
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>10.0</version>
</dependency>
在构建项目时确实已加载库Saxon-HE-10.0.jar。
我的java方法去了(为此尝试,inputFile发送任何格式正确的xml文件):
public File transfoTest(InputStream inputFile) throws Exception {
logger.debug("Begin transformation test");
File output = File.createTempFile("output",".xml");
output.deleteOnExit();
InputStream xslFile = getClass().getResourceAsstream("/xslTransformerFiles/transfoXSLT.xsl");
OutputStream osOutputFile = FileUtils.openOutputStream(output);
PrintStream printStream = new PrintStream(osOutputFile);
StreamSource xsrc = new StreamSource(xslFile);
TransformerFactory transformerFactory = net.sf.saxon.TransformerFactoryImpl.newInstance();
Transformer xsltTransformer = transformerFactory.newTransformer(xsrc);
xsltTransformer.transform(new StreamSource(inputFile),new StreamResult(printStream));
inputFile.close();
xslFile.close();
osOutputFile.close();
printStream.close();
logger.debug("End transformation test");
return output;
}
这是transfoXSLT.xsl:
<?xml version="1.1" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<xsl:value-of select="'xsl:version: '" />
<xsl:value-of select="system-property('xsl:version')" />
</xsl:template>
</xsl:stylesheet>
这是令人失望的输出:
<?xml version="1.0" encoding="UTF-8"?>
xsl:version: 1
解决方法
调用net.sf.saxon.TransformerFactoryImpl.newInstance()
时,这是一个静态方法,实际上根本没有调用Saxon方法。您正在调用在javax.xml.transform.TransformerFactory()
上定义的方法。我不确定为什么这会为您提供XSLT 1.0转换器工厂(这取决于许多因素,例如类路径上JAR文件的精确顺序),但这当然不是确保您的身份的可靠方法。正在加载撒克逊人。
它也很慢:它涉及搜索类路径。
如果您想加载Saxon,请按照MarcStröbel的建议使用new net.sf.saxon.TransformerFactoryImpl()
显式加载。或更妙的是,放弃JAXP并使用Saxon s9api接口,可以更好地访问2.0和3.0功能。