如何在Tomcat服务器上运行XSLT2转换?

huangapple go评论85阅读模式
英文:

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: 对于扩展函数,找不到方法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("开始转换测试");
    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("结束转换测试");
    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
英文:

I am trying to run a XSLT 2.0 transformation from a XML file on a Tomcat v8.0 Server.
However, I only succeed in running it as XSLT1.

Anytime I try to use a XSLT2 function, I get such an error:
> org.apache.xml.utils.WrappedRuntimeException: java.lang.NoSuchMethodException: For extension function, could not find method org.apache.xml.utils.NodeVector.root([ExpressionContext,] ).

I am using Saxon, here is the pom declaration:

		&lt;dependency&gt;
			&lt;groupId&gt;net.sf.saxon&lt;/groupId&gt;
			&lt;artifactId&gt;Saxon-HE&lt;/artifactId&gt;
			&lt;version&gt;10.0&lt;/version&gt;
		&lt;/dependency&gt;

The library Saxon-HE-10.0.jar is indeed loaded when I build the project.

My java method goes (for the sake of this try, inputFile sends any well-formed xml file):

	public File transfoTest(InputStream inputFile) throws Exception  {
		logger.debug(&quot;Begin transformation test&quot;);
		File output =  File.createTempFile(&quot;output&quot;, &quot;.xml&quot;);
		output.deleteOnExit();
		InputStream xslFile = getClass().getResourceAsStream(&quot;/xslTransformerFiles/transfoXSLT.xsl&quot;);
		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(&quot;End transformation test&quot;);
		return output;	
	}

Here is transfoXSLT.xsl:

&lt;?xml version=&quot;1.1&quot; encoding=&quot;UTF-8&quot; ?&gt;
&lt;xsl:stylesheet version=&quot;2.0&quot;
  xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
	&lt;xsl:output method=&quot;xml&quot; encoding=&quot;UTF-8&quot; indent=&quot;yes&quot; /&gt;
	&lt;xsl:template match=&quot;/&quot;&gt;
		&lt;xsl:value-of select=&quot;&#39;xsl:version: &#39;&quot; /&gt;
		&lt;xsl:value-of select=&quot;system-property(&#39;xsl:version&#39;)&quot; /&gt;
	&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

And here is the disappointing output:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
xsl:version: 1

答案1

得分: 1

当您调用net.sf.saxon.TransformerFactoryImpl.newInstance()时,这是一个静态方法,实际上您并没有调用Saxon的方法;您正在调用javax.xml.transform.TransformerFactory()上定义的方法。我不确定为什么会给您一个XSLT 1.0转换器工厂(它取决于许多因素,例如类路径上JAR文件的精确顺序),但肯定不能可靠地确保您正在加载Saxon。

这也很慢:它涉及搜索类路径。

如果您知道您想要加载Saxon,可以使用new net.sf.saxon.TransformerFactoryImpl()来显式加载,就像Marc Ströbel建议的那样。或者更好的是,放弃使用JAXP,改用Saxon的s9api接口,这样可以更好地访问2.0和3.0的功能。

英文:

When you call net.sf.saxon.TransformerFactoryImpl.newInstance(), this is a static method, and you're not actually calling a Saxon method at all; you're calling a method defined on javax.xml.transform.TransformerFactory(). I'm not sure exactly why this is giving you an XSLT 1.0 transformer factory (it depends on many factors, such as the precise order of JAR files on your classpath), but it certainly isn't a reliable way of ensuring that you are loading Saxon.

It's also slow: it involves searching the classpath.

If you know you want to load Saxon, load it explicitly using new net.sf.saxon.TransformerFactoryImpl() as suggested by Marc Ströbel. Or better still, abandon JAXP and use the Saxon s9api interfaces, which give much better access to 2.0 and 3.0 capabilities.

huangapple
  • 本文由 发表于 2020年8月26日 17:23:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/63594532.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定