• Home

Logo

Navigation
  • Home
  • Articles
    • Content Writing
    • Design
    • General
    • Internet Marketing
    • Social Media
    • Tools and Tips
    • Usability
    • Web Hosting Articles
  • Tutorials
    • AJAX Tutorials
    • ASP Tutorials
    • C# Tutorials
    • CGI and Perl Tutorials
    • CSS Tutorials
    • Flash Tutorials
    • HTML Tutorials
    • Illustrator Tutorials
    • Java Tutorials
    • JavaScript Tutorials
    • Linux Tutorials
    • Miscellaneous Tutorials
    • MySQL Tutorials
    • Photoshop Tutorials
    • PHP Tutorials
    • Python Tutorials
    • Wireless Tutorials
    • WordPress Tutorials
    • XML Tutorials
  • Scripts
    • AJAX Scripts
    • ASP Scripts
    • ASP.NET Scripts
    • CGI & Perl Scripts
    • Flash Scripts
    • Java Scripts
    • JavaScript Scripts
    • PHP Scripts
    • Python Scripts
    • Remotely Hosted
    • Tools and Utilities
    • XML Scripts
  • Answers
  • Online Services
  • Tools

Tip: Create Multiple Files in XSLT 2.0

By Jack Herrington | on May 16, 2005 | 0 Comment
XML Tutorials
  • Tweet
  • Share
  • Tweet
  • Share

Use a single XSLT template to create multiple files

For any reasonably complex data set, you need multiple views to navigate it. Take a QA test system, for example: With a pool of tests and test results, you need to see the data by date, by test category, by individual test, and so on. Each view would be in its own HTML file. So, can you have a single template in XSLT 2.0 build multiple HTML files from the one input data set?

The first version of XSLT was very strict. It had one input and one output (although you could have more than one template file). Version 2 of the standard still restricts you to one input, but the output system is more flexible. Now, you can have multiple output files using the xsl:result-document directive. This new tag has two key attributes, as shown in Table 1.

Table 1. xsl:result-document attributes

Attribute Description
href The file name or fully qualified URL of the output file
format The name of the format to use as defined in a corresponding xsl:output directive

To test this directive, I have one input XML file that includes a set of test results (see Listing 1).

Listing 1. The input XML file



<?xml version="1.0" encoding="UTF-8"?>
<tests>
<testrun run="test1">
<test name="foo" pass="true" />
<test name="bar" pass="true" />
<test name="baz" pass="true" />
</testrun>
<testrun run="test2">
<test name="foo" pass="true" />
<test name="bar" pass="false" />
<test name="baz" pass="false" />
</testrun>
<testrun run="test3">
<test name="foo" pass="false" />
<test name="bar" pass="true" />
<test name="baz" pass="false" />
</testrun>
</tests>

This is pretty simple stuff. Within each test run is a set of named tests with the pass flag, which tells you whether the test was successful.

Create a file for each test

The first thing I need to do is create a file for each test result. Listing 2 shows the XSL template.Listing 2. Code to create a file for each test



<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">

<xsl:output method="text"/>
<xsl:output method="html" indent="yes" name="html"/>

<xsl:template match="/">
<xsl:for-each select="//testrun">
<xsl:variable name="filename"
select="concat('output1/',@run,'.html')" />
<xsl:value-of select="$filename" /> <!-- Creating -->
<xsl:result-document href="{$filename}" format="html">
<html><body>
<xsl:value-of select="@run"/>
</body></html>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

A few things are worth noting, starting right at the top of the file. The version attribute on the stylesheet tag is set to 2.0 so that you can use the xsl:result-document tag. After that, you see that the stylesheet itself is set to text as the output type. This means that if I want the HTML files to have HTML formatting, I need to define a second named format of type html. I use this format in the xsl:result-document tag.

From there, I use an xsl:for-each loop to iterate through the testrun tags. Within each of those tags, I use the variable tag to create a new $filename variable that concatenates the output directory name (output1), the name of the run, and the .html file extension into a single path.

With that in hand, I tell the user what files I’m creating by using the value-of tag with my $filename variable. Then, I open the new document with the xsl:result-document tag and output the HTML. Listing 3 shows the output of the engine when it’s run on the sample data file.

Listing 3. The output of Saxon when run on the sample data file



Creating output1/test1.html
Creating output1/test2.html
Creating output1/test3.html

Get better output

It seems somehow counterintuitive that the contents of the xsl:result-document tag are evaluated in the same way as the rest of the template, but they are. And all the variables within the template context are available.

To demonstrate this, I’ve upgraded the code within the xsl:result-document tag to provide more information about the results of the test (see Listing 4).

Listing 4. Better HTML output from the template



<xsl:result-document href="{$filename}" format="html">
<html><head>
<title>Test results - <xsl:value-of select="@run"/></title>
</head><body>
<xsl:value-of select="@run"/> <!-- Run -->
<table>
<tr><td>Test</td><td>Pass</td></tr>
<xsl:for-each select="test">
<tr><td>
<xsl:value-of select="@name" />
</td><td>
<xsl:value-of select="@pass" />
</td></tr>
</xsl:for-each>
</table>
</body></html>
</xsl:result-document>

See Listing 5 for the HTML result of this output.

Listing 5. The upgraded HTML output



<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">

<title>Test results - test1</title>
</head>
<body>
<!-- Run: test1-->
<table>
<tr>
<td>Test</td>
<td>Pass</td>
</tr>
<tr>
<td>foo</td>
<td>true</td>
</tr>
<tr>
<td>bar</td>
<td>true</td>
</tr>
<tr>
<td>baz</td>
<td>true</td>
</tr>
</table>
</body>
</html>

Create an index

To finish, I need to add an index file that points to all the output test results. To do that, I use another xsl:result-document tag and hard-code the output to go to an index file (see Listing 6).

Listing 6. Code to build the index file



<!-- Creating the index -->
<xsl:result-document href="output3/index.html"
format="html">
<html><head><title>Test Index</title></head>
<body>
<xsl:for-each select="//testrun">
<a href="{@run}.html"><xsl:value-of select="@run" />
</a><br/>
</xsl:for-each>
</body>
</html>
</xsl:result-document>

This section goes right after the xsl:for-each loop that builds the HTML files for each test case. Listing 7 shows the index file for the example data set.

Listing 7. The index file



<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">

<title>Test Index</title>
</head>
<body><a href="test1.html">test1</a><br>
<a href="test2.html">test2</a><br>
<a href="test3.html">test3</a><br></body>
</html>

Summary

Using the xsl:result-document directive, you can have a single XSL template output to multiple files from a single data source. This functionality, which was a nonstandard extension in XSLT 1.x, opens a world of opportunity for XSLT template authors.

Resources

  • Visit the XSL standards site at the W3C, a handy reference to XSL technologies and standards.
  • Check out the XPath page at the W3C, which provides version and standard information.
  • Download Saxon, the popular XSL processor that the author used to create this article.
  • Read Michael Kay?s XSLT 2.0 Programmer’s Reference, the bible of XSLT. It?s a fantastic introduction and a valuable reference work.
  • While you’re at it, pick up XPath 2.0 Programmer’s Reference by Michael Kay — the ultimate reference by the man who wrote the W3C specification.
  • Read Code Generation in Action by Jack D. Herrington, which covers generating code for a wide variety of targets not limited to database access.
  • Find hundreds more XML resources on the developerWorks XML zone.
  • Learn how you can become an IBM Certified Developer in XML and related technologies.
  • Share this story:
    • tweet

    Author Description

    An engineer with with more than 20 years of experience, Jack Herrington is currently Editor-in-Chief of the Code Generation Network. He is the author of Code Generation in Action . You can contact him at jack_d_herrington@codegeneration.net.

    No Responses to “Tip: Create Multiple Files in XSLT 2.0”

    You must be logged in to post a comment.

    Connect With Us

    RSSSubscribe 0Followers 496Likes
    • Popular
    • Recent
    • Comments
    • Creating Energy Spheres in Photoshop

      Apr 15, 2008 - 96 Comments
    • Easy Screen Scraping in PHP with the Simple HTML DOM Library

      Aug 6, 2008 - 20 Comments
    • Calculating date difference more precisely in PHP

      Mar 7, 2008 - 13 Comments
    • When Does Hosting Your Website in the Cloud Make Sense?

      Oct 8, 2010 - 2 Comments
    • Fun with the Microsoft Managed Extensibility Framework Part 2

      Oct 6, 2010 - 0 Comment
    • Fun with the Microsoft Managed Extensibility Framework Part 1

      Sep 22, 2010 - 0 Comment
    • Website Management on the go with the iPad

      I appreciated your post, but I was looking for something I didn't...
      November 24, 2012 - drmoderator
    • Creating Energy Spheres in Photoshop

      I'm a little stuck down here especially at the step of creating the...
      November 23, 2012 - sarah
    • Running background processes in PHP

      Can you give an example? As see it, you can use this only when you...
      November 16, 2012 - Shaked Klein Orbach
    Developer Resources
    • Tutorial Directory
    • Learn HTML
    • Learn PHP
    • Learn CSS
    • Learn AJAX
    • Learn JavaScript
    • Learn Pear
    • White Papers
  • Resources
    • NetVisits Web Directory
    • Realtor Pixels
    • Answers On The Run
    • Ask A Geek
  • Recent Posts

    • When Does Hosting Your Website in the Cloud Make Sense?
    • Fun with the Microsoft Managed Extensibility Framework Part 2
    • Fun with the Microsoft Managed Extensibility Framework Part 1
    • Website Management on the go with the iPad
    • Code Contracts in C# 4.0 – Part 1

    Calendar

    June 2013
    M T W T F S S
    « Oct    
     12
    3456789
    10111213141516
    17181920212223
    24252627282930

    Recent Comments

    • drmoderator on Website Management on the go with the iPad
    • sarah on Creating Energy Spheres in Photoshop
    • Shaked Klein Orbach on Running background processes in PHP
    • Thomas Cuvillier on How To Upload Files Using PHP
    • rizal aditya on Extracting text from Word Documents via PHP and COM
    • Home
    © 2003 - 2013 DeveloperTutorials.com. All Rights Reserved. Privacy Policy.