Pregunta

I tienen una serie de XSL 2.0 hojas de estilo que se alimentan entre sí, es decir, la salida de hoja de estilo A alimenta B alimenta C.

¿Cuál es la forma más eficiente de hacer esto? La pregunta es reformulado:. ¿Cómo puede una ruta eficiente la salida de una transformación en otro

Aquí está mi primer intento:

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

Como se puede ver, estoy usando un DOM para sentarse en medio de transformaciones, y aunque es conveniente, es no óptimo rendimiento inteligente.

¿Hay alguna forma fácil de ruta decir, una ruta SAXResult a un SAXSource? Una solución StAX sería otra opción.

Estoy al tanto de proyectos como XProc , que es muy bien si usted no ha echado un vistazo a, sin embargo, pero yo no quería invertir en su conjunto un marco.

¿Fue útil?

Solución

He encontrado esto: # 3. Encadenamiento de Transformaciones que muestra dos formas de usar el TransformerFactory a las transformaciones de la cadena, que tiene los resultados de uno transforman alimentación la siguiente transformada y, finalmente, la salida a sistema fuera. Esto evita la necesidad de una serialización intermedio de cadena, archivo, etc., entre las transformadas.

  

Cuando múltiple, sucesiva   transformaciones son necesarios para la   mismo documento XML, asegúrese de evitar   las operaciones de análisis innecesarios. yo   con frecuencia ejecutar en código que   transforma una cadena a otra cadena,   a continuación, se transforma a esa cadena aún   otra cadena. Esto no sólo es lento,   pero puede consumir una significativa   cantidad de memoria y, sobre todo   Si las cadenas intermedias no son   permitido ser basura recogida.

     

La mayoría de las transformaciones se basan en una   serie de eventos SAX. Un analizador SAX   típicamente analizar un InputStream o   otra InputSource en eventos SAX,   que luego pueden ser alimentados a una   Transformador. En lugar de tener la   transformador de salida a un archivo, cadena,   u otro tal resultado, un SAXResult   se puede utilizar en su lugar. Un SAXResult   acepta un ContentHandler, que puede   pasar estos eventos SAX directamente a   otro transformador, etc.

     

Este es un enfoque, y la que yo   por lo general prefieren, ya que proporciona más   flexibilidad para diversos entrada y   fuentes de salida. También hace que sea   bastante fácil para crear una transformación   cadena dinámicamente y con una variable   número de transformaciones.

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.

Otros consejos

Lo mejor es atenerse a DOM como que estás haciendo, porque un procesador XSLT tendría que construir un árbol de todos modos - streaming es sólo una opción para categoría muy limitada de transformaciones, y pocos o ninguno de los procesadores pueden averiguarlo automáticamente y cambiar a una aplicación de streaming de sólo; de lo contrario se acaba de leer la entrada y construir el árbol.

tubería XSLT eficiente, con parametros, en Java esclarecido sobre parámetros correctos que pasan a dicha cadena transformador.

Y también dio una pista en la solución un poco más corto y sin tercer transformador:

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));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top