如何使用Java使用XSL转换XML

我目前正在使用标准的javax.xml.transform库,使用XSL将我的XML转换为CSV。 我的XSL文件很大 – 大约950行。 我的XML文件也可能非常大。

它在原型阶段运行良好,只有一小部分XSL在大约50行左右。 现在在“最终系统”中,当它执行变换时,它会出现错误分支目标偏移量太大而不是简短

private String transformXML() { String formattedOutput = ""; try { TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer( new StreamSource( xslFilename ) ); StreamSource xmlSource = new StreamSource(new ByteArrayInputStream( xmlString.getBytes() ) ); ByteArrayOutputStream baos = new ByteArrayOutputStream(); transformer.transform( xmlSource, new StreamResult( baos ) ); formattedOutput = baos.toString(); } catch( Exception e ) { e.printStackTrace(); } return formattedOutput; } 

我发现了一些有关此错误的post但不太确定该怎么做。
我做错了代码吗? 有没有可用的替代第三方变压器可以做到这一点?

谢谢,

Andez

试试撒克逊 。

您的代码将保持不变。 您需要做的就是在JVM的系统属性中将javax.xml.transform.TransformerFactory设置为net.sf.saxon.TransformerFactoryImpl

使用撒克逊。 offtop:如果使用相同的样式表来转换许多XML文件,您可能需要考虑模板(预编译的样式表):

 javax.xml.transform.Templates style = tFactory.newTemplates(xslSource);
 。style.newTransformer()变换(...);

我在网上发现了一个提到apache XALAN的post。 所以我把jar子加到了我的项目中。 一切都已开始工作,即使我没有直接引用我的代码中的任何XALAN类。 据我所知,仍然应该使用jaxax.xml类。

不太确定那里发生了什么。 但它正在发挥作用。

作为Saxon的替代方案,您可以将大型模板拆分为较小的模板。

XSLT样式表中包含的模板定义由SAP JVM的XSLT编译器“Xalan”编译为Java方法,以便更快地执行转换。 这些Java方法中包含的Java字节码分支指令限制为32K偏移。 大模板定义现在可以导致非常大的Java方法,其中分支偏移量需要大于32K。 因此,这些样式表无法编译为Java方法,因此无法用于转换。

由于XSLT样式表的每个模板定义都编译为单独的Java方法,因此可以使用多个较小的模板作为解决方案。 通过使用“ call-template ”元素,可以将非常大的模板分解为多个较小的模板。

本文深入介绍了XSLT样式表的大小限制 。

旁注:如果saxon不可用,我只会建议将此作为最后的手段 ,因为这需要对xsl文件进行相当多的更改。