効率的なXSLTのJavaでパイプライン(またはソースに結果をリダイレクト)

StackOverflow https://stackoverflow.com/questions/1312406

質問

私はお互いに供給XSLスタイルシート2.0のシリーズを持っている、スタイルシートAの、すなわち出力はBがCを供給するフィード

これを行うための最も効率的な方法は何ですか?言い換え質問です:どのように1は、効率的にルート別に1つの変換の出力をすることができます。

ここに私の最初の試みです

@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を使用していて、それは便利ですが、それは非最適なパフォーマンスが賢明です。

と言うにルーティングする簡単な方法、てSAXSourceへのルートSAXResultはありますか? StAXのソリューションは、別のオプションになります。

私はあなたがまだ見て取られていない場合は非常にクールである、 XPROC のようなプロジェクトの承知しています、しかし、私は、全体の枠組みの中で投資したくありませんでした。

役に立ちましたか?

解決

私はこれを見つけた: #3。そのの連鎖変換は、一つの結果は、フィードをシステムに次最後に、次に変換して出力を変換有する、鎖変換にのTransformerFactoryの]を使用する2つの方法を示しています。これは、変換の間などの文字列、ファイル、中間直列化の必要性を回避する。

  

場合、複数の連続します   変換はする必要があります   同じXML文書は、避けるようにしてください   不要な解析作業。私   頻繁にそのコードに実行   別の文字列に文字列を変換し、   その後、まだその文字列に変換します   別の文字列。だけでなく、これは遅いです、   しかし、それは大きなを消費することができます   メモリの量だけでなく、特に   中間文字列がない場合は   ごみを収集することが許されます。

     

ほとんどの変換はに基づいています   SAXの一連のイベント。 SAXパーサ   一般的にInputStreamを解析したりします   SAXイベントに別のInputSource、   これはその後に供給することができます   変成器。むしろ持つより   ファイルへのトランス出力、文字列、   または他のこのような結果、SAXResult   代わりに使用することができます。 SAXResult   缶のContentHandlerは、受け入れ   直接これらのSAXイベントに渡します   別の変圧器など。

     

ここに1つのアプローチ、および1つのIであります   それはより多くを提供して通常好みます   様々な入力のための柔軟性と   出力ソース。また、それを作ります   変換を作成することはかなり簡単   チェーン動的変数と   変換の数。

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.

他のヒント

あなたの最善の策は、あなたがやっているようXSLTプロセッサはとにかくツリーを構築する必要があるため、DOMに固執することです - ストリーミングのみ変換の非常に限られたカテゴリのオプション、およびいくつかの任意のプロセッサがそれを把握することができれば自動的にストリーミングのみの実装に切り替えます。そうでなければ、ただの入力を読み込み、ツリーを構築します。

関連質問の中のparamsとhref="https://stackoverflow.com/questions/3517352/efficient-xslt-pipeline-with-params-in-java">効率的なXSLTパイプライン、そのようなトランス鎖に渡す正しいパラメータに明らかにした。

そしてそれはまた、第三のトランスずに少し短いソリューションのヒントを与えます:

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

Templates templates1 = stf.newTemplates(new StreamSource(
        getClass().getResourceAsStream("MyStylesheet1.xslt")));
Templates templates2 = stf.newTemplates(new StreamSource(
        getClass().getResourceAsStream("MyStylesheet2.xslt")));

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

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

// Note that indent, etc should be applied to the last transformer in chain:
th2.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");

th1.getTransformer().transform(new StreamSource(System.in), new SAXResult(th2));
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top