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

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

Earlier releases of AltovaXML had incomplete support for the
format-date()
function: the date was output, but not in the requested format. This is fixed in the 2008 release.

copyright.xsl

Finally, the module
copyright.xsl
contains a named template that outputs a copyright statement. This template is called by the

instruction in the principal stylesheet. The template uses a variable
$owner
to construct the copyright statement; we'll see later how this is useful.


      xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”

      version=“1.0”>

John Wiley and Sons


   Copyright © 

   

    2007



The reason for separating this stylesheet program into three modules is that the
date.xsl
and
copyright.xsl
modules are reusable in other stylesheets. Functionally, the stylesheet would have exactly the same effect if the variable
$date
and the template named
copyright
were defined directly in the principal stylesheet module.

Output



   Michael Kay

   XSLT 2.0 Programmer's Reference

   Copyright © John Wiley and Sons 2007

   October 3rd, 2007

   A comprehensive guide to the XSLT 2.0 recommendation published by the World Wide Web Consortium 


There is no syntactic difference between a principal stylesheet module and any other module; in fact any module can be used as a principal module.

This means that

and

can be used in any module, not only the principal module. So the stylesheet program is actually a tree of stylesheet modules, with the principal module at its root.

A stylesheet module is generally a complete XML document (the exception, an
embedded stylesheet
, will be described later on page 102). The document element (the outermost element of the XML document) is then either an

element or an

element; the two names are synonymous. The elements immediately subordinate to the

or

element are called
declarations
. The XSLT-defined declarations are listed on page 105.

The

and

declarations are always children of the

or

element. Usually, declarations can appear in any order, but

is an exception: it must appear before any other declaration. Both elements take an
href
attribute whose value is a URI. Most commonly, it will be a relative URI, defining the location of the included or imported stylesheet module relative to the parent module. For example,

fetches the module
mod1.xsl
located in the same directory as the parent module.

The difference between

and

is that conflicting definitions are resolved differently:


  • effectively does a textual inclusion of the referenced stylesheet module, minus its containing

    element, at the point where the

    element is written. The included module is treated exactly as if its top-level elements, with their contents, appeared in the parent module in place of the

    element itself.

  • also incorporates the top-level elements from the referenced stylesheet module, but in this case the declarations in the imported module have lower
    import precedence
    than the declarations in the parent module. If there are conflicting declarations, the one with higher import precedence will generally win. The detailed rules actually depend on the type of definition, and are given in the specification of

    on page 357 in Chapter 6. Importing a module is thus rather like defining a subclass, in that the parent module can use some declarations unchanged from the imported module, and override others with declarations of its own.

It may not come naturally to think of the importing module as a subclass of the imported module, because in a class hierarchy, the most general classes are near the root of the tree, whereas in the

tree, the most general classes are at the leaves of the tree. Nevertheless, this is how

should be used: general-purpose modules should always be imported into special-purpose modules, not the other way around.

The most common kind of declaration is the definition of a template rule, using an

element with a
match
attribute. As we saw in the previous chapter, if there are several template rules that match a particular node in the source tree, the first step in deciding which to use is to look at their import precedence, and discard all those with import precedence less than the highest. So a template rule defined in a particular stylesheet module will automatically take precedence over another matching rule in a module that it imports.

Where one module A imports two others, B and C, as shown in
Figure 3-1
, then A takes precedence over both B and C, and C also takes precedence over B, assuming that the

element that loads B precedes the

element that loads C.

When a stylesheet incorporates another using

, the declarations in the included stylesheet have the same import precedence as those in the parent stylesheet.

Where two declarations have the same import precedence (because they were in the same stylesheet module, or because one was in a module incorporated in the other using

), the rules for resolving conflicts depend on the kind of declaration. In some cases, for example declarations of named templates or variables, duplicate declarations with the same name are always reported as an error. In other cases, for example declarations of template rules, the implementor has the choice of reporting an error or choosing the declaration that occurs later in the stylesheet. Some implementors may pass this choice on to the user. The detailed rules are given in Chapter 6 for each kind of declaration, and they are summarized in the section for

, page 357.

Example: Using

This extends the previous

example, showing how to use

to incorporate the declarations in another stylesheet module while overriding some of them.

Source

The input document for this example is
sample.xml
.

Stylesheet

Recall that the
copyright.xsl
module used a variable,
$owner
, to hold the name of the copyright owner. Suppose that we want to use the
copyright
template, but with a different copyright owner. We can achieve this by writing a revised principal stylesheet as follows (this is called
principal2.xsl
in the downloadable sample files).

This stylesheet uses

instead of

to incorporate the
copyright.xsl
module, and it then contains a new declaration of the
$owner
variable, which will override the declaration in the imported module. Note that the

element must come first.


      xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”

      version=“1.0”

>


John Wiley Inc.





   



   



   

      

      

   



Output



   Michael Kay

   XSLT Programmer's Reference

   Copyright © John Wiley Inc 2007

   April 28th, 2007

   A comprehensive guide to the XSLT 2.0 recommendation published by the World Wide Web Consortium 


This example wouldn't work if you used

rather than

. It would complain that the variable
$owner
was declared twice. This is because with

, the two declarations have the same import precedence, so neither can override the other.

It is an error for a stylesheet module to import or include itself, directly or indirectly, because doing so would define an infinite loop.

It isn't an error, however, for a stylesheet module to be included or imported at more than one place in the stylesheet program. The following isn't an error.


   

   


This may seem rather pointless, but in a highly modular structure it can sometimes happen by accident and be harmless. For example, several of your stylesheet modules might independently reference a commonly used module such as
date.xsl
. The effect is simply to load two copies of all the declarations in
date.xsl
, exactly as if two identical files with different names had been imported.

If the same module is fetched twice using

, the included declarations will have the same import precedence, which is likely to cause an error. If, for example, the included module defines a global variable or a named template, duplicate declarations will be reported. In other cases, for example where the file uses the

element to define named attribute sets, the duplicate declarations are harmless (the

element is described on page 266, in Chapter 6). However, if there is a risk of loading the same module twice, it makes sense to use

rather than

.

Note that with both

and

, the
href
attribute is fixed: it is possible for a stylesheet compiler to assemble all the modules in a stylesheet well before a source document is supplied to actually run the transformation. People often ask for some kind of facility to load stylesheet modules dynamically, based on a decision made while the transformation is running. The simple answer is that you can't do this: you have to construct the whole stylesheet before you can start running it.

Sometimes, this requirement arises when people try to use

“the wrong way round.” It's fairly natural to think in terms of writing a general-purpose stylesheet G that imports A in some circumstances (say if the user is French) and imports B in other circumstances (if the user is Spanish). But that's the wrong way to do it: you should select A or B as the principal stylesheet module, and have both of these import the general-purpose module G. The special-purpose stylesheet module should always import the general-purpose module.

Other books

Sweet Kiss by Judy Ann Davis
Tangled by Carolyn Mackler
The Law of Moses by Amy Harmon
Shooting 007: And Other Celluloid Adventures by Alec Mills, Sir Roger Moore
Highways & Hostages by Jax Abbey
Forbidden Desires by Banerjee, Madhuri