Injecting Parameters into a XSL Transform Using the Java JAXP API

Posted by & filed under Uncategorized.

Often XML transformation is done with a static XML document or one generated from a data source.  Sometimes a transform needs environment or other runtime information in the transform process.  For example, I needed the absolute base path and a CSS stylesheet for a HTML document I was creating, and this was not something that could be static.  Using the Java JAXP API, its possible to inject parameters into the transform process by calling the Transformer setParameter method prior to calling transform.  In the XSL stylesheet you declare the parameter using xsl:param at the top of the document just after the xsl:stylesheet declaration.  The parameter is then available anywhere in the XSL template through the $parameter notation.

Here’s the java code.

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class XSLTransformer {
   ...
   public void transform(Source xmlSource, Source xslSource, Result result) throws Exception
   {
      final TransformerFactory tFactory = TransformerFactory.newInstance();
      tFactory.setErrorListener(errorListener);
      final Transformer transformer = tFactory.newTransformer(xslSource);
      transformer.setParameter("path", getPath());
      transformer.setParameter("theme", getTheme())
      transformer.transform(xmlSource, result);
   }
   ...
}

Here is the XSL stylesheet template.

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:param name="path"  />
   <xsl:param name="theme"  />
   <xsl:output method="xml" version="1.0" omit-xml-declaration="yes"
      media-type="text/html" indent="no" encoding="UTF-8" />

   <xsl:template match="/">

   ...

   <xsl:element name="link">
      <xsl:attribute name="rel">
         <xsl:text>stylesheet</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="type">
         <xsl:text>text/css</xsl:text>
      </xsl:attribute>
      <xsl:attribute name="href">
         <xsl:value-of select="$path" />
      <xsl:text>css/</xsl:text>
         <xsl:value-of select="$theme" />
      </xsl:attribute>
   </xsl:element>

   ...

   </xsl:template>
</xsl:stylesheet>