java - Java 中的高效 XSLT 管道(或将结果重定向到源)

标签 java xslt dom sax pipeline

我有一系列相互馈送的 XSL 2.0 样式表,即样式表 A 的输出馈送 B 馈送 C。

最有效的方法是什么?重新表述的问题是:如何有效地将一种转换的输出路由到另一种转换。

这是我的第一次尝试:

@Override
public void transform(Source data, Result out) throws TransformerException{
    for(Transformer autobot : autobots){
        if(autobots.indexOf(autobot) != (autobots.size()-1)){
            log.debug("Transforming prelim stylesheet...");
            data = transform(autobot,data);
        }else{
            log.debug("Transforming final stylesheet...");
            autobot.transform(data, out);
        }
    }
}

private Source transform(Transformer autobot, Source data) throws TransformerException{
    DOMResult result = new DOMResult();
    autobot.transform(data, result);
    Node node = result.getNode();
    return new DOMSource(node);
}

如您所见,我在转换之间使用 DOM,虽然它很方便,但在性能方面并不理想。

是否有任何简单的路由方法可以将 SAXResult 路由到 SAXSource? StAX 解决方案将是另一种选择。

我知道像 XProc 这样的项目,如果您还没有看的话,这很酷,但我不想投资整个框架。

最佳答案

我发现了这个:#3. Chaining Transformations这显示了使用 TransformerFactory 链接转换的两种方法,将一个转换的结果馈送到下一个转换,然后最终输出到系统输出。这避免了在转换之间对字符串、文件等进行中间序列化的需要。

When multiple, successive transformations are required to the same XML document, be sure to avoid unnecessary parsing operations. I frequently run into code that transforms a String to another String, then transforms that String to yet another String. Not only is this slow, but it can consume a significant amount of memory as well, especially if the intermediate Strings aren't allowed to be garbage collected.

Most transformations are based on a series of SAX events. A SAX parser will typically parse an InputStream or another InputSource into SAX events, which can then be fed to a Transformer. Rather than having the Transformer output to a File, String, or another such Result, a SAXResult can be used instead. A SAXResult accepts a ContentHandler, which can pass these SAX events directly to another Transformer, etc.

Here is one approach, and the one I usually prefer as it provides more flexibility for various input and output sources. It also makes it fairly easy to create a transformation chain dynamically and with a variable number of transformations.

SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance();

// These templates objects could be reused and obtained from elsewhere.
Templates templates1 = stf.newTemplates(new StreamSource(
  getClass().getResourceAsStream("MyStylesheet1.xslt")));
Templates templates2 = stf.newTemplates(new StreamSource(
  getClass().getResourceAsStream("MyStylesheet1.xslt")));

TransformerHandler th1 = stf.newTransformerHandler(templates1);
TransformerHandler th2 = stf.newTransformerHandler(templates2);

th1.setResult(new SAXResult(th2));
th2.setResult(new StreamResult(System.out));

Transformer t = stf.newTransformer();
t.transform(new StreamSource(System.in), new SAXResult(th1));

// th1 feeds th2, which in turn feeds System.out.

关于java - Java 中的高效 XSLT 管道(或将结果重定向到源),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1312406/

相关文章:

java - 修改函数无法打印预期结果

java - 如何让应用程序不自行重置?

html - XSLT 转换 - INNERHTML

javascript - 如何解决 "Could not convert JavaScript argument arg 0 [nsIDOMHTMLDivElement.appendChild]"错误

php - 如何使用 PHP Simple HTML DOM Parser 在 HTML 文件中找到最后一个 <div class>?

html - HTML 中的清除表单按钮……我们真的需要这个吗?

java hibernate CLASS 不是 bean

java - 如何使用流 API 根据条件对行进行排序

xslt 2.0变量元素节点集处理

html - XSLT 值得吗?