Java 中的高效 XSLT 管道(或将结果重定向到源) [英] Efficient XSLT pipeline in Java (or redirecting Results to Sources)

查看:23
本文介绍了Java 中的高效 XSLT 管道(或将结果重定向到源)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a series of XSL 2.0 stylesheets that feed into each other, i.e. the output of stylesheet A feeds B feeds C.

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

What is the most efficient way of doing this? The question rephrased is: how can one efficiently route the output of one transformation into another.

这是我的第一次尝试:

@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 来进行转换,虽然它很方便,但在性能方面并不是最佳的.

As you can see, I'm using a DOM to sit in between transformations, and although it is convenient, it's non-optimal performance wise.

有什么简单的路由方法可以说,将 SAXResult 路由到 SAXSource?StAX 解决方案将是另一种选择.

Is there any easy way to route to say, route a SAXResult to a SAXSource? A StAX solution would be another option.

我知道像 XProc 这样的项目,如果你还没有看的话,它非常酷,但我不想投资整个框架.

I'm aware of projects like XProc, which is very cool if you haven't taken a look at yet, but I didn't want to invest in a whole framework.

推荐答案

我发现了这个:#3.链式转换 展示了使用 TransformerFactory 来链式转换的两种方式,让一个转换的结果提供给下一个转换,然后最终输出到系统输出.这避免了在转换之间对字符串、文件等进行中间序列化的需要.

I found this: #3. Chaining Transformations that shows two ways to use the TransformerFactory to chain transformations, having the results of one transform feed the next transform and then finally output to system out. This avoids the need for an intermediate serialization to String, file, etc. between transforms.

当多个时,连续需要转换到同一个 XML 文档,一定要避免不必要的解析操作.一世经常遇到这样的代码将一个字符串转换为另一个字符串,然后将该字符串转换为尚未另一个字符串.不仅速度慢,但它可以消耗大量内存量也很大,尤其是如果中间字符串不是允许被垃圾收集.

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.

大多数转换都基于一系列 SAX 事件.SAX 解析器通常会解析 InputStream 或另一个 InputSource 到 SAX 事件中,然后可以将其送入变压器.而不是拥有变压器输出到文件、字符串、或另一个这样的结果,一个 SAXResult可以代替.一个 SAXResult接受一个 ContentHandler,它可以将这些 SAX 事件直接传递给另一个变压器等

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 中的高效 XSLT 管道(或将结果重定向到源)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆