如何在 Tomcat 服务器上 [=11a XSLT 转换?

How to run a XSLT2 tranformation on a Tomcat server?

我正在尝试 运行 从 Tomcat v8.0 服务器上的 XML 文件进行 XSLT 2.0 转换。 但是,我只成功 运行 将其设置为 XSLT1。

每当我尝试使用 XSLT2 函数时,都会收到这样的错误:

org.apache.xml.utils.WrappedRuntimeException: java.lang.NoSuchMethodException: For extension function, could not find method 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,请按照 Marc Ströbel 的建议使用 new net.sf.saxon.TransformerFactoryImpl() 显式加载它。或者更好的是,放弃 JAXP 并使用 Saxon s9api 接口,这样可以更好地访问 2.0 和 3.0 功能。