Saying
Our project, containing many different xslt files, generates many different outputs (e.g: code that uses DB2 SQL, or Oracle SQL, or DAO, or some other flavor of code). This results in usage of indirect calls to handle different generation options, however to allow xslt to work we had to create a big main xslt including stylesheets for each kind of generation. This impacts on a compilation time.
Alternatives
We were eagerly inclined to the second alternative. Unfortunately a limited set of information is available when "use-when" is evaluated. In particular there are neither parameters nor documents available. Using Saxon's extensions one may reach only static variables, or access System.getProperty(). This isn't flexible.
We've decided to try the third alternative.
Solution
We think we have found a nice solution: to create XsltSource, which receives a list of includes upon construction, and creates an xslt when getReader() is called.
XsltSource
getReader()
import java.io.Reader; import java.io.StringReader; import javax.xml.transform.stream.StreamSource; /** * A source to read generated stylesheet, which includes other stylesheets. */ public class XsltSource extends StreamSource { /** * Creates an {@link XsltSource} instance. */ public XsltSource() { } /** * Creates an {@link XsltSource} instance. * @param systemId a system identifier for root xslt. */ public XsltSource(String systemId) { super(systemId); } /** * Creates an {@link XsltSource} instance. * @param systemId a system identifier for root xslt. * @param includes a list of includes. */ public XsltSource(String systemId, String[] includes) { super(systemId); this.includes = includes; } /** * Gets stylesheet version. * @return a stylesheet version. */ public String getVersion() { return version; } /** * Sets a stylesheet version. * @param value a stylesheet version. */ public void setVersion(String value) { version = value; } /** * Gets a list of includes. * @return a list of includes. */ public String[] getIncludes() { return includes; } /** * Sets a list of includes. * @param value a list of includes. */ public void setIncludes(String[] value) { includes = value; } /** * Generates an xslt on the fly. */ public Reader getReader() { String[] includes = getIncludes(); if (includes == null) { return super.getReader(); } String version = getVersion(); if (version == null) { version = "2.0"; } StringBuilder builder = new StringBuilder(1024); builder.append("<stylesheet version=\""); builder.append(version); builder.append("\" xmlns=\"http://www.w3.org/1999/XSL/Transform\">"); for(String include: includes) { builder.append("<include href=\""); builder.append(include); builder.append("\"/>"); } builder.append("</stylesheet>"); return new StringReader(builder.toString()); } /** * An xslt version. By default 2.0 is used. */ private String version; /** * A list of includes. */ private String[] includes; }
To use it one just needs to write:
Source source = new XsltSource(base, stylesheets); Templates templates = transformerFactory.newTemplates(source); ...
where:
base
stylesheets
Such implementation resembles a dynamic linking when separate parts are bound at runtime. We would like to see dynamic modules in the next version of xslt.
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u