XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (692 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
7.18Mb size Format: txt, pdf, ePub

              select=“seconds-from-time(current-time()) mod 1.0e0”

              use-when=“not(function-available(‘random:random-sequence’, 2))”

              xmlns:random=“http://exslt.org/random”/>

              select=“random:random-sequence(1, ())”

              use-when=“function-available(‘random:random-sequence’, 2)”

              xmlns:random=“http://exslt.org/random”/>

(In fact, the
use-when
attribute on the first

declaration is not strictly needed, assuming these are local variables. If the
use-when
attribute on the second variable evaluates to true, this variable will shadow the first variable, and it does no harm for both variables to be present.)

Note that the rules for the
use-when
attribute require it to be a condition that can be evaluated at compile time. It's therefore not permitted in this expression to reference the values of variables or stylesheet parameters, or to access the contents of a source document.

You can use similar techniques to make a stylesheet portable between different XSLT versions. In this case there are additional facilities available, notably the
[xsl:]version
attribute, which can be attached to any element in the stylesheet. Version compatibility is fully discussed in Chapter 3, on page 128.

Summary

Extension functions are useful to extend the capabilities of XSLT stylesheets. They allow stylesheets to access external system services and to perform calculations that are difficult or inefficient to achieve in “pure” XSLT and XPath.

There are other extensibility mechanisms in XSLT, including extension instructions, extension declarations, and extension attributes, but extension functions are by far the most widely used, so that's what we concentrated on in this chapter.

In the next chapter, we move away from detailed specifications of interfaces and look at using the facilities of XSLT to create well-designed stylesheets.

Chapter 17

Stylesheet Design Patterns

This chapter looks at four common design patterns for XSLT stylesheets.

The concept of design patterns was introduced by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides in their classic book
Design Patterns: Elements of Reusable Object-Oriented Software
(Addison-Wesley Publishing, 1995). Their idea was that there was a repertoire of techniques that were useful again and again. They presented 23 different design patterns for object-oriented programming, claiming not that this was a complete list but that the vast majority of programs written by experienced designers fell into one or more of these patterns.

For XSLT stylesheets, the vast majority of stylesheets I have seen fall into one of four design patterns. These are as follows:

  • Fill-in-the-blanks stylesheets
  • Navigational stylesheets
  • Rule-based stylesheets
  • Computational stylesheets

Again, this doesn't mean that these are the only ways you can write stylesheets, nor does it mean that any stylesheet you write must follow one of these four patterns to the exclusion of the other three. It just means that a great many stylesheets actually written by experienced people follow one of these four patterns, and if you become familiar with these patterns, you will have a good repertoire of techniques that you can apply to solving any given problem.

I describe the first three design patterns rather briefly, because they are not really very difficult. The fourth, the computational design pattern, is explored in much greater depth—not because it is encountered more often, but because it requires a different way of thinking about algorithms than you use with conventional procedural programming languages.

Fill-in-the-Blanks Stylesheets

Many proprietary templating languages have been built up around HTML. The template looks largely like a standard HTML file but with the addition of extra tags used to retrieve variable data and insert it at a particular point in the HTML data page. The designers of XSLT took care to ensure that, in spite of the power of XSLT as a full transformation language, it would still be possible to use it in this simple way, bringing it within the reach of nonprogrammers with HTML authoring skills.

Example: A “Fill-in-the-Blanks” Stylesheet

Here's an example of such a stylesheet. It uses the
simplified stylesheet
syntax, so the

element and the

element are implicit.

Input

This XML document,
orgchart.xml
, represents an organization chart showing the senior management of a certain company at a particular date. It is organized as a recursive structure that directly reflects the management hierarchy. You may recognize the names, but the roles are entirely fictitious.




   Tim Berners-Lee

   Chief Executive Officer

   

      

         Sharon Adler

         Technical Director

         

            

               Tim Bray

               Chief Engineer

            

            

               James Clark

               Director of Research

            

         

      

      

         Henry Thompson

         Operations and Finance

      

      

         David Megginson

         Human Resources

      

      

         Steve Muench

         Marketing

      

      

         Scott Boag

         International

      

   


Stylesheet

There are many creative ways to display this data; for example, you could use SVG graphics, Explorer-style trees implemented in client-side JavaScript, or just indented lists. I'm not trying to teach you any clever HTML tricks, so in this stylesheet (
orgchart.xsl
) I'll show the data instead, as a rather boring table, with one row per person and three columns for the person's name, their title, and the name of their boss.

      xsl:version=“2.0”>


      Management Structure



   Management Structure

   

The following responsibilities were announced on

      

                                         ‘[D1] [MNn] [Y1]’)”/>:


   

   

     NameRoleReporting to

   

   

      

          

          

          

      

   

   

   





The key to this design pattern is that the stylesheet has the same structure as the desired output. Fixed content is included directly in the stylesheet as text or as literal result elements, while variable content is included by means of

instructions that extract the relevant data from the source document. Repeated sections of output, typically rows in a table or items in a list, can be enclosed by

, and conditional sections by

or

.

Output

The output of this stylesheet is shown in
Figure 17-1
.

This kind of stylesheet makes very limited use of XSLT's power, but it is very similar to a wide variety of proprietary templating languages currently in use. Experience has shown that this kind of stylesheet is easy for experienced HTML authors to write, even if they have no programming training. This is an important consideration, because on many larger Web sites there is a constant need to introduce new page templates at very short notice, and this becomes much easier to achieve if content authors and editors can do the work themselves.

One restriction, of course, is that the input has to come from an XML document. This contrasts with most of the proprietary languages, where the input often comes directly from a relational database. Fortunately, all popular relational databases now provide convenient ways to extract data from a database in XML form. Ideally, this doesn't even need to be a serial XML document that has to be re-parsed by the XSLT processor. It will often be possible to transfer the data directly from the database to the XSLT processor in a structured form; for example, as a DOM tree in memory or as a SAX event stream. The details of how to do this depend on the database product you are using and are beyond the scope of this book.

Another approach is to use the
document()
function (described in Chapter 13, page 754) with a URI that addresses a servlet with parameters to retrieve the required data.

Navigational Stylesheets

Navigational stylesheets are a natural progression from simple fill-in-the-blanks stylesheets.

Like fill-in-the-blanks stylesheets, a navigational stylesheet is still essentially output-oriented. However, it is now likely to use named templates or stylesheet functions as subroutines to perform commonly needed tasks; it may use variables to calculate values needed in more than one place, and it may use constructs such as keys, parameters, and sorting.

Whereas a fill-in-the-blanks stylesheet looks like HTML sprinkled with a few extra control statements, a navigational stylesheet (once you look beyond the angle-bracket syntax) has a rather similar structure to a conventional procedural program with variables, conditional statements, for loops, and subroutine calls.

Navigational stylesheets are often used to produce reports on data-oriented XML documents, where the structure of the source document is regular and predictable.

Example: A Navigational Stylesheet

This example shows the use of a navigational stylesheet to produce a very simple sales report.

Input

Suppose the source document,
booklist.xml
, looks like this:



   

      Angela's Ashes

      Frank McCourt

      HarperCollins

      0 00 649840 X

      6.99

      235

   

   

      Sword of Honour

      Evelyn Waugh

      Penguin Books

      0 14 018967 X

      12.99

      12

   


Stylesheet

The following navigational stylesheet (
booksales.xsl
) produces a report on the total number of sales for each publisher.

   xmlns:xs=“http://www.w3.org/2001/XMLSchema”

   exclude-result-prefixes=“xs”

   version=“2.0”>


We need to declare a variable that refers to the input document, for later use in a named template that has no context node.


The global variable
$publishers
is a sequence of strings containing one string for each distinct publisher found in the source file. This uses the new
distinct-values()
function introduced in XPath 2.0.

   select=“distinct-values(/booklist/book/publisher)”/>

The main template iterates over the distinct publishers using

.




   Sales volume by publisher



   Sales volume by publisher

   


      


         


      


      

         


            


            


         


      

   

PublisherTotal Sales Value




Finally, a named template that calculates the total sales for the publisher. The name of the publisher is supplied as an implicit parameter in the context node; however, to make the template more reusable a parameter is declared with this as the default.


   

   



This stylesheet is not very far removed from the fill-in-the-blanks example earlier in the chapter. But because it uses some top-level elements such as

and a named template, it now needs to use the full syntax with an

element.

Output

The output is shown in
Figure 17-2
.

Other books

This Old Souse by Mary Daheim
Diseased by Jeremy Perry
The Indwelling: The Beast Takes Possession by Lahaye, Tim, Jenkins, Jerry B.
Fielder's Choice by Aares, Pamela
Reapers by Kim Richardson
Joel Rosenberg - [D'Shai 01] - D'Shai by Joel Rosenberg - [D'Shai 01]
Trace of Innocence by Erica Orloff