La respuesta más común a esta pregunta describe una técnica para poner en práctica una tubería XSLT eficiente en Java:tubería XSLT eficiente, con parametros, en Java
Efficient XSLT pipeline in Java (or redirecting Results to Sources)
Lamentablemente, si bien Transformador parece exponer una API para establecer Parámetros XSLT, esto no parece tener ningún efecto. Por ejemplo, tengo el siguiente código:
Transformer.java
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.Templates;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.Transformer;
import java.io.File;
public class MyTransformer {
public static void main(String[] args) throws javax.xml.transform.TransformerConfigurationException, javax.xml.transform.TransformerException{
SAXTransformerFactory stf = (SAXTransformerFactory)TransformerFactory.newInstance();
// These templates objects could be reused and obtained from elsewhere.
Templates templates1 = stf.newTemplates(new StreamSource(new File("MyStylesheet1.xslt")));
Templates templates2 = stf.newTemplates(new StreamSource(new File("MyStylesheet2.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();
//SETTING PARAMETERS HERE
t.setParameter("foo","this is from param 1");
t.setParameter("bar","this is from param 2");
t.transform(new StreamSource(new File("in.xml")), new SAXResult(th1));
// th1 feeds th2, which in turn feeds System.out.
}
}
MyStylesheet1.xslt
<?xml version="1.0"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0">
<output method="xml"/>
<param name="foo"/>
<template match="@*|node()">
<copy>
<apply-templates select="@*|node()"/>
</copy>
</template>
<template match="foo:my/foo:hello">
<copy>
<foo:world>
foo is : <value-of select="$foo"/>
</foo:world>
</copy>
</template>
</stylesheet>
MyStylesheet2.xslt
<?xml version="1.0"?>
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:foo="urn:foo" version="1.0">
<output method="xml"/>
<param name="bar"/>
<template match="@*|node()">
<copy>
<apply-templates select="@*|node()"/>
</copy>
</template>
<template match="foo:my/foo:hello/foo:world">
<copy>
<apply-templates select="@*|node()"/>
<attribute name="attr">
<value-of select="$bar"/>
</attribute>
</copy>
</template>
</stylesheet>
in.xml
<my xmlns="urn:foo">
<hello/>
</my>
Lo que me da el siguiente resultado:
<?xml version="1.0" encoding="UTF-8"?><my xmlns="urn:foo">
<hello><foo:world xmlns:foo="urn:foo">foo is : </foo:world></hello>
</my>
Como se puede ver foo: El Mundo/@ attr está vacía, y los contenidos de texto de foo: mundo dice "foo es:". El comportamiento esperado es que deberían haberse completado con los parámetros pasados al método setParameter.
Hay una manera de establecer los parámetros de transformación XSL utilizando esta técnica. Si no, ¿alguien podría recomendar una técnica alternativa para transformar las hojas de estilo de manera eficiente en Java, de modo que los parámetros XSLT también puedan establecerse?