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

Chr*_*ott 19 java xslt dom pipeline sax

我有一系列相互馈送的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);
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在使用DOM来处理转换之间,虽然它很方便,但它并不是非最佳性能.

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

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

Mad*_*sen 23

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

当同一XML文档需要多次连续转换时,请务必避免不必要的解析操作.我经常遇到将String转换为另一个String的代码,然后将该String转换为另一个String.这不仅速度慢,而且还会占用大量内存,特别是如果不允许中间字符串被垃圾收集.

大多数转换都基于一系列SAX事件.SAX解析器通常会将InputStream或另一个InputSource解析为SAX事件,然后可以将其提供给Transformer.不是将Transformer输出到File,String或其他此类Result,而是可以使用SAXResult.SAXResult接受ContentHandler,它可以将这些SAX事件直接传递给另一个Transformer等.

这是一种方法,也是我通常喜欢的方法,因为它为各种输入和输出源提供了更大的灵活性.它还使得动态创建转换链并使用可变数量的转换变得相当容易.

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.
Run Code Online (Sandbox Code Playgroud)

  • 太好了,看起来就像我正在寻找的.只是好奇 - 你搜索到了什么?我的google-foo必须生锈. (3认同)
  • 实际上,你的问题让我想起了我曾经看过的一些代码.我知道它使用了saxtransformerfactory,所以我用Google搜索:"saxtransformerfactory链转换".考虑到在管道转换时节省了多少代码/逻辑/故障,这似乎很难找到. (2认同)