如何使用Java使用XSL转换XML

时间:2010-11-04 09:29:03

标签: java xml transform xslt

我目前正在使用标准的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;
}

我发现了一些有关此错误的帖子但不太确定该怎么做 我做错了代码吗? 是否有可以做到这一点的替代第三方变形金刚?

谢谢,

Andez

4 个答案:

答案 0 :(得分:4)

请尝试Saxon

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:0)

作为Saxon的替代品,您可以将大型模板拆分为更小的模板。

  

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

<强>解决方案

  

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

本文Size limitation for XSLT stylesheets对此进行了深入介绍。

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