Hack 37 Generate an XSLT Identity Stylesheet with Relaxer

figs/moderate.gif figs/hack37.gif

Quickly generate XSLT stylesheets with Asami Tomoharu's Relaxer.

Relaxer (http://www.relaxer.org) is a Java schema compiler for XML. Relaxer can generate Java classes [Hack #99] based on RELAX NG, DTDs, XML Schema, and RELAX Core schemas (http://www.xml.gr.jp/relax/). It can also generate schemas (see [Hack #73], [Hack #74], and [Hack #75] ) from one or more XML documents. There are many other things Relaxer can do, but in this hack I want to focus on its ability to generate XSLT stylesheets based on one or more XML documents. Generating a stylesheet with Relaxer can give you a start for designing your own stylesheets. It's quite easy to use and merits some of our attention.

You can download Version 1.0 of Relaxer (relaxer-1.0.zip) from http://www.relaxer.org/download/index.html. After downloading the file, you can run the installation script by typing this line, assuming of course that you have Java on your system:

java -jar relaxer-1.0.zip

The script will ask you where you want to install Relaxer:

Install directory [default: C:\usr\local\lib\relaxer]: c:\lib

Command directory [default: C:\usr\local\bin]: c:\bin

If you are on Windows and submitted c:\lib and c:\bin, for example, the script will respond:

[Configuration]

Install directory = c:\lib

Command directory = c:\bin

   

Type "yes" to install, "no" to re-enter, "exit" to exit

>

Use whatever directories are appropriate for your system. If you type yes here, you will see this report:

Extract archives...

Generate script...

  script = c:\bin\relaxer.bat

  script = c:\bin\relaxer

Done.

Now check the Relaxer version:

relaxer -version

This should yield:

Copyright(c) 2000-2003 ASAMI,Tomoharu. All rights reserved.

Relaxer Version 1.0 (20031224) by asami@relaxer.org

Now you're ready to generate an XSLT stylesheet with Relaxer. You'll use a file called gen.xml, which is identical to time.xml (Example 3-11).

Example 3-11. gen.xml
<?xml version="1.0" encoding="UTF-8"?>

   

<!-- a time instant -->

<time timezone="PST">

 <hour>11</hour>

 <minute>59</minute>

 <second>59</second>

 <meridiem>p.m.</meridiem>

 <atomic signal="true"/>

</time>

Use the -xslt switch to generate the stylesheet, and the -verbose switch to see what Relaxer's doing during processing time:

relaxer -verbose -xslt gen.xml

You should see this:

Copyright(c) 2000-2003 ASAMI,Tomoharu. All rights reserved.

Relaxer Version 1.0 (20031224) by asami@relaxer.org

Source file     : file:/C:/Hacks/examples/gen.xml

        artifact = gen.xsl

Relaxer generated the artifact gen.xsl. It's a simple stylesheet that mirrors gen.xml and can perform an identity transform on gen.xml (Example 3-12).

Example 3-12. gen.xsl
<?xml version='1.0'?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes" method="xml"/>

  <xsl:template match="minute">

    <minute>

      <xsl:apply-templates/>

    </minute>

  </xsl:template>

  <xsl:template match="atomic">

    <atomic>

      <xsl:attribute name="signal">

        <xsl:value-of select="@signal"/>

      </xsl:attribute>

      <xsl:apply-templates/>

    </atomic>

  </xsl:template>

  <xsl:template match="meridiem">

    <meridiem>

      <xsl:apply-templates/>

    </meridiem>

  </xsl:template>

  <xsl:template match="second">

    <second>

      <xsl:apply-templates/>

    </second>

  </xsl:template>

  <xsl:template match="time[hour and minute and second and 

    meridiem and atomic]">

    <time>

      <xsl:attribute name="timezone">

        <xsl:value-of select="@timezone"/>

      </xsl:attribute>

      <xsl:apply-templates/>

    </time>

  </xsl:template>

  <xsl:template match="hour">

    <hour>

      <xsl:apply-templates/>

    </hour>

  </xsl:template>

</xsl:stylesheet>

Apply this stylesheet to gen.xml:

xalan gen.xml gen.xsl

and you'll get a close copy of the original:

<?xml version="1.0" encoding="UTF-8"?>

<time timezone="PST">

 <hour>11</hour>

 <minute>59</minute>

 <second>59</second>

 <meridiem>p.m.</meridiem>

 <atomic signal="true"/>

</time>

Generating stylesheets is quick and easy to do with Relaxer. It will provide you with a ready-made stylesheet that you can then edit for your own purposes. You could also use Relaxer to programmatically generate a series of stylesheets based on one or more instance documents.