【问题标题】:How to transform XML with XSL using Java如何使用 Java 使用 XSL 转换 XML
【发布时间】:2011-05-04 23:06:12
【问题描述】:

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

它在原型阶段运行良好,其中一小部分 XSL 大约 50 行左右。现在在“最终系统”中,当它执行转换时会出现错误Branch target offset too large for short

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;
}

我遇到了一些关于此错误的帖子,但不太确定该怎么做。
我在代码方面做错了什么吗? 是否有其他可用的第三方变压器可以做到这一点?

谢谢,

安德斯

【问题讨论】:

  • 不要使用xmlString.getBytes(),它会使用默认的平台编码将字符串转换为字节,这可能不是您想要的,因此您的代码依赖于平台。而是使用new StreamSource(new StringReader( xmlString ) ),或者更可取的是,如果从输入流中读取xmlString 并将其转换为字符串,则只需使用流中的字节而不是先将它们转换为字符串,这可能也取决于平台。

标签: java xml transform xslt


【解决方案1】:

改用Saxon

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我在网上看到一篇提到 apache XALAN 的帖子。所以我将罐子添加到我的项目中。尽管我没有在我的代码中直接引用任何 XALAN 类,但一切都已经开始工作了。据我所知,它仍然应该使用 jaxax.xml 类。

      不太清楚那里发生了什么。但它正在工作。

      【讨论】:

        【解决方案4】:

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

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

        解决方案

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

        Size limitation for XSLT stylesheets这篇文章中有深入描述。

        旁注:如果没有 saxon,我只推荐将此作为最后的手段,因为这需要对您的 xsl 文件进行大量更改。

        【讨论】:

          猜你喜欢
          • 2012-08-12
          • 2016-02-13
          • 1970-01-01
          • 2012-02-01
          • 2013-06-23
          • 2022-01-09
          • 1970-01-01
          • 2011-12-31
          相关资源
          最近更新 更多