SourceForge Logo

mtxslt - Multi-XSLT Ant Task

Anthony B. Coates

abcoates@TheOffice.net

| Download mtxslt from SourceForge |

News

2002-12: mtxslt @ XML.com
mtxslt is featured in an article on XML.com describing how to use Ant for XSLT. The source for the article (DocBook used by the author, and XHTML as submitted to XML.com) is available in a ZIP archive (56K).

What is "mtxslt"?

mtxslt is an Ant task that makes it easy to call multiple XSLT engines during a single Ant build. This makes Ant a suitable tool for co-ordinating regression testing of XSLT scripts, so that they run portably.

Why would I want to use more than one XSLT engine?

You may be happy with the XSLT engine that you use, and you may only write XSLT scripts for internal consumption, so that you never need portability across XSLT engines. If that is the case, there is probably no advantage to you in using mtxslt. However, if at any stage you do find that you need to work with multiple XSLT engines, it is easy to switch from using the standard xslt/style task to using mtxslt.

It is important to be aware that different groups of users use different XSLT engines. Many XML consultants use Saxon, from Michael Kay of Software AG. Groups using Apache Cocoon or Jetspeed for the Web sites are likely to use Apache Xalan. Oracle shops are likely to use the Oracle XDK. Windows developers are likely to use the MSXML COM object. While conformance between the engines is good, and improving, it can still be a challenge to make XSLT stylesheets 100% portable, hence the need to test with every XSLT engine that your scripts are likely to be used with.

mtxslt currently supports Java XSLT engines: Saxon 6/7, Xalan for Java 2, and Oracle XDK for Java 9. A future project is to see if a suitable Java/COM bridge can be used to make MSXML available for use within Ant when running on Windows.

Why not just use the existing Ant "xslt/style" task?

The existing Ant "xslt" or "style" task (you are allowed to use either name) uses the JAXP/TraX interface to run the XSLT engine. With JAXP, the Java system property javax.xml.transform.TransformerFactory can be set to the name of the factory class to use for creating XSLT transformers (engines).

However, it is not straightforward to set Java system properties from within an Ant build, and less so if you need to keep changing the transformer factory so that you can use multiple XSLT engines within the one build.

This is the reason for mtxslt, which minimally extends the standard xslt/style task to easily support the use of multiple XSLT engines. mtxslt is released under version 1.1 of the Apache Software License.

Using mtxslt

As mtxslt is an extension of the standard Ant xslt/style task, you need to read the instructions for the standards xslt/style task first. Have you done that yet? OK, now for an example. Suppose you have an input file called input.xml, and an XSLT stylesheet called transform.xsl, which produces an HTML output file. You want to apply this stylesheet to the input file using the different XSLT engines currently supported by mtxslt.

Step 1 is to add the file path for mtxslt.jar to your CLASSPATH environment variable, so that mtxslt is available to Ant. In the usual fashion, the Ant build file will be called build.xml.

To perform the transform using the standard xslt/style task, and the default JAXP/TraX XSLT engine, your build.xml would contain

<xslt processor = "trax"
      in = "input.xml"
      style = "transform.xsl"
      out = "output.html"/>

or

<style processor = "trax"
       in = "input.xml"
       style = "transform.xsl"
       out = "output.html"/>

To make mtxslt available to Ant, you need to define its matching Java task class in your build.xml.

<taskdef name = "mtxslt"
         classname = "org.xmLP.ant.taskdefs.xslt.XSLTProcess"/>

Then you can use mtxslt as you would use the standard xslt/style task.

<mtxslt processor = "trax"
        in = "input.xml"
        style = "transform.xsl"
        out = "mt-output.html"/>

The processor value (for both xslt/style and mtxslt) can also be the name of a suitable XSLT engine liaison class. The standard xslt/style task uses org.apache.tools.ant.taskdefs.optional.TraXLiaison, so a longer way of achieving the same transform is as follows (note the use of an Ant property called trax to make the code easier to read):

<property name = "trax"
          value = "org.xmLP.ant.taskdefs.optional.TraXLiaison"/>
...
<xslt processor = "${trax}"
      in = "input.xml"
      style = "transform.xsl"
      out = "output.html"/>
<mtxslt processor = "${trax}"
        in = "input.xml"
        style = "transform.xsl"
        out = "mt-output.html"/>

Now, mtxslt is able to call multiple XSLT engines because it provides specific liaison classes for each engine. This bypasses the normal JAXP/TraX mechanism for selecting the transformer factory class. Do not be worried that mtxslt bypasses the standard JAXP/TraX mechanism. The TraX API authors were not thinking about the problem of using multiple XSLT engines simultaneously when they wrote the API, and so mtxslt has to provide its own work-around.

So, the following sample shows how to call different XSLT engines using mtxslt. Note again the use of Ant properties to make the code easier to read. You need to set the correct class paths for your own system, of course:

<!-- Apache Xalan for Java 2 -->
<property name = "xalan2"
          value = "org.xmLP.ant.taskdefs.optional.Xalan2Liaison"/>
<property name = "xalan2.classpath"
          value = "C:\XSLT\xalan-j_2_2_0\bin\xalan.jar"/>

<!-- Saxon 6 -->
<property name = "saxon6"
          value = "org.xmLP.ant.taskdefs.optional.Saxon6Liaison"/>
<property name = "saxon6.classpath"
          value = "C:\XSLT\Saxon-6.5.2\saxon.jar"/>

<!-- Saxon 7 -->
<property name = "saxon7"
          value = "org.xmLP.ant.taskdefs.optional.Saxon7Liaison"/>
<property name = "saxon7.classpath"
          value = "C:\XSLT\Saxon-7.1\saxon7.jar"/>

<!-- Oracle XDK 9 -->
<property name = "oracle9"
          value = "org.xmLP.ant.taskdefs.optional.Oracle9Liaison"/>
<property name = "oracle9.classpath"
          value = "C:\XSLT\xdk_java_9_2_0_3_0\lib\xmlparserv2.jar"/>	

With these property values set, mtxslt can now be called for each XSLT engine within the same Ant build. Note that the standard xslt/style classpath property is used to set the class path for each XSLT engine:

<mtxslt processor = "${xalan2}"
        in = "input.xml"
        style = "transform.xsl"
        out = "xalan2.html"
        classpath = "${xalan2.classpath}"/>
<mtxslt processor = "${saxon6}"
        in = "input.xml"
        style = "transform.xsl"
        out = "saxon6.html"
        classpath = "${saxon6.classpath}"/>
<mtxslt processor = "${saxon7}"
        in = "input.xml"
        style = "transform.xsl"
        out = "saxon7.html"
        classpath = "${saxon7.classpath}"/>
<mtxslt processor = "${oracle9}"
        in = "input.xml"
        style = "transform.xsl"
        out = "oracle9.html"
        classpath = "${oracle9.classpath}"/>

And that is it. Once you have the required definitions at the top of your build.xml, mtxslt is no more difficult to use than the usual xslt/style task.

How to get mtxslt

mtxslt is available from SourceForge. The version number matches the version number of the Ant xslt/style code which was extended to produce mtxslt.

References

  1. Apache Jakarta Ant build environment
  2. Ant xslt/style task
  3. JAXP/Trax interface for XSLT engines

Last updated: 24th December, 2002.

SourceForge Logo