Frage

ich eine Reihe von XSL 2.0 Sheets haben, die ineinander zuzuführen, das heißt das Ausgangssignal des A Sheet speist B C speist.

Was ist der effizienteste Weg, dies zu tun? Die Frage neu formuliert ist. Wie kann man effizient zu routen der Ausgang einer Transformation in ein anderes

Hier ist mein erster Versuch:

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

Wie Sie sehen können, bin ich ein DOM zwischen Transformationen zu sitzen, und obwohl es bequem ist, es ist nicht optimale Leistung klug.

Gibt es eine einfache Möglichkeit, um den Weg zu sagen, route ein SAXResult zu einem SAXSource? Eine StAX Lösung wäre eine weitere Option.

Ich bin mir dessen bewusst Projekte wie XProc , was sehr cool ist, wenn man nicht einen Blick auf noch getroffen haben, aber ich wollte nicht in einem ganzen Rahmen investieren.

War es hilfreich?

Lösung

Ich fand dies: #3. Transformations Chaining dass zwei Möglichkeiten zeigt die verwenden TransformerFactory , um Ketten Transformationen, wobei die Ergebnisse einer Vorschub verwandeln die nächste Transformation und dann schließlich Ausgabe-System aus. Dadurch entfällt die Notwendigkeit für eine Zwischen Serialisierung String, Datei usw. zwischen Transformationen.

  

Wenn mehrere aufeinanderfolgende   Transformationen werden auf die erforderliche   gleiches XML-Dokument, sollten Sie vermeiden   unnötige Parsing-Operationen. ich   häufig laufen in Code,   verwandelt einen String an einen anderen String,   dann verwandelt sich diese String noch   ein anderer String. Dies ist nicht nur langsam,   aber es kann eine erhebliche verbrauchen   Speichermenge als auch vor allem   wenn die Zwischen Strings sind nicht   erlaubt Müll gesammelt werden.

     

sind die meisten Transformationen basiert auf einem System   Serie von SAX Ereignisse. Ein SAX-Parser   wird in der Regel einen Inputstream analysieren oder   eine andere Input in SAX Ereignisse,   die dann auf ein zugeführt werden   Transformator. Anstatt die mit   Transformator Ausgabe in eine Datei, String,   oder ein anderes solches Ergebnis, ein SAXResult   kann stattdessen verwendet werden. Ein SAXResult   akzeptiert ein Content, die kann   passieren diese SAX Ereignisse direkt an   ein weiterer Transformator, etc.

     

Hier ist ein Ansatz, und die, die ich   in der Regel bevorzugen, da es mehr bietet   Flexibilität für verschiedene Ein- und   Ausgabequellen. Es macht es auch   ziemlich einfach, eine Transformation zu erstellen   Kette dynamisch und mit einem variablen   Anzahl der Transformationen.

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.

Andere Tipps

Ihre beste Wette ist, um DOM zu bleiben, wie Sie tun, weil ein XSLT-Prozessor ohnehin einen Baum bauen würde - Streaming ist nur eine Option für sehr begrenzte Gruppe von Transformationen, und wenige, wenn irgendwelche Prozessoren können es herausfinden automatisch und wechseln Sie zu einer Streaming-only Umsetzung; sie lesen nur die Eingabe sonst und den Baum zu bauen.

Verwandte Frage Efficient XSLT-Pipeline, mit params, in Java korrekten Parameter geklärt auf solchen Transformator Kette übergeben.

Und es gab auch einen Hinweis auf etwas kürzere Lösung ohne dritten Transformator:

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));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top