Hack 45 Generate Multiple Output Documents with XSLT 2.0

   

figs/moderate.gif figs/hack45.gif

Unlike XSLT 1.0, XSLT 2.0 allows you to produce more than one result tree from a single transformation.

XSLT 2.0 has added the functionality to serialize more than one result tree when performing a single transformation with the new result-document element. The stylesheet in this hack will show you how to produce four result documents from one source document.

The result-document.xsl stylesheet produces four result trees based on time.xml. The default result tree is output as text, and the remaining three are output as XML, HTML, and XHTML, respectively. The stylesheet is listed in Example 3-28.

Example 3-28. result-document.xsl
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:output name="xml" method="xml" indent="yes"/> <xsl:output name="html" method="html" indent="yes"/> <xsl:output name="xhtml" method="xhtml" indent="yes"/> <xsl:param name="dir">file:///C:/Hacks/examples/</xsl:param>     <xsl:template match="/">      <xsl:apply-templates select="time" mode="text"/>      <xsl:result-document format="xml" href="{$dir}/rd.xml">   <time>    <xsl:message terminate="no">Printing XML result tree in rd.xml...</xsl:message>    <xsl:apply-templates select="time" mode="xml"/>   </time>  </xsl:result-document>  <xsl:result-document format="html" href="{$dir}/rd.html">   <xsl:message terminate="no">Printing HTML result tree in rd.html... </xsl:message>    <html>    <body>    <h2>Time</h2>     <ul>      <xsl:apply-templates select="time" mode="html"/>     </ul>    </body>    </html>   </xsl:result-document>       <xsl:result-document format="xhtml" href="{$dir}/rd-x.html">    <xsl:message terminate="no">Printing XHTML result tree in rd-x.html... </xsl:message>     <html xmlns="http://www.w3.org/1999/xhtml">     <body>     <h2>Time</h2>      <ul>       <xsl:apply-templates select="time" mode="xhtml"/>      </ul>     </body>     </html>   </xsl:result-document>   <xsl:message terminate="no">Printing text result tree...</xsl:message> </xsl:template> <xsl:template match="time" mode="text">  <xsl:value-of select="hour"/>:<xsl:value-of select="minute"/>:<xsl:value-of select="second"/ ><xsl:text> </xsl:text><xsl:value-of select="meridiem"/> </xsl:template>     <xsl:template match="time" mode="xml">  <hr><xsl:value-of select="hour"/></hr>  <min><xsl:value-of select="minute"/></min>  <sec><xsl:value-of select="second"/></sec>  <mer><xsl:value-of select="meridiem"/></mer> </xsl:template> <xsl:template match="time" mode="html">  <li><xsl:value-of select="hour"/></li>  <li><xsl:value-of select="minute"/></li>  <li><xsl:value-of select="second"/></li>  <li><xsl:value-of select="meridiem"/></li> </xsl:template> <xsl:template match="time" mode="xhtml">  <li xmlns="http://www.w3.org/1999/xhtml"><xsl:value-of select="hour"/></li>  <li xmlns="http://www.w3.org/1999/xhtml"><xsl:value-of select="minute"/></li>  <li xmlns="http://www.w3.org/1999/xhtml"><xsl:value-of select="second"/></li>  <li xmlns="http://www.w3.org/1999/xhtml"><xsl:value-of select="meridiem"/></li> </xsl:template> </xsl:stylesheet>

The version attribute on the stylesheet element (line 1) has a value of 2.0 because it's a 2.0 stylesheet. On lines 2-5 are four output elements, three of them named. This is so that a result-document element can reference an output element by name.

The global parameter dir declared on line 6 stores the name of the directory where the three result trees are to be written as files. The attribute value template {$dir} in the href attributes (on lines 12, 19, and 31) passes in a value for the dir parameter. If you want to change where the output files are written, you can edit the content of the param element on line 6.

The template matching / creates a text result tree. Each of the other three result trees are inside result-document elements, and each creates a message using the message element. Each result tree also applies templates to time elements, each in a different mode (text, xml, html, and xhtml). The different modes for each result help create an appropriate tree for each of the given formats.

You need to use the Java version of Saxon, preferably Version 8.0 or later, to get this to work. Saxon 8.0 is available from http://saxon.sourceforge.net. Once everything is installed, you can type this command:

java -jar saxon8.jar time.xml result-document.xsl

You get the following messages:

Printing XML result tree in rd.xml... Printing HTML result tree in rd.html... Printing XHTML result tree in rd-x.html... Printing text result tree... 11:59:59 p.m.

The last line shows the text output of the transformation. The files that the three result-document elements produced contain the other result trees. The first one is rd.xml:

<?xml version="1.0" encoding="UTF-8"?> <time>    <hr>11</hr>    <min>59</min>    <sec>59</sec>    <mer>p.m.</mer> </time>

The second one is rd.html, which contains simple HTML:

<html>    <body>       <h2>Time</h2>       <ul>          <li>11</li>          <li>59</li>          <li>59</li>          <li>p.m.</li>       </ul>    </body> </html>

And the final document is rd-x.html, a simple XHTML document:

<html xmlns="http://www.w3.org/1999/xhtml">    <body>       <h2>Time</h2>       <ul>          <li>11</li>          <li>59</li>          <li>59</li>          <li>p.m.</li>       </ul>    </body> </html>

If you're still using XSLT 1.0, you can probably produce multiple result documents, but it will be through extension features that vary from processor to processor.



XML Hacks
XML Hacks: 100 Industrial-Strength Tips and Tools
ISBN: 0596007116
EAN: 2147483647
Year: 2006
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net