Chapter 18. XSL Transformations (XSLT) Friendly Tutorial

  • Template rules

  • Patterns

  • Templates

  • Referencing stylesheets

We have seen XSLT used at a high level in other chapters, now we’ll look at the details of how it works. But be aware that the full details on XSLT could fill a book[1] and we don’t cover them all here. The objective of this chapter is to provide a basic understanding for the way that XSLT stylesheets cause XML documents to be processed.

Transforming vs. rendering

XSL was designed to apply style to an XML document by using XSLT to transform it into a rendition, represented by XSL formatting objects (XSL-FO). The XSL processor may then display the rendered document on a screen, print it, or convert it to some other rendition representation, such as PDF, PostScript, or even voice synthesis!

But “style” in the world of generalized markup encompasses every kind of processing. The transformation could be very powerful and complex, as XSLT can reorder, duplicate, suppress, sort, and add elements. There are many applications besides formatting where such transformations would be useful.

Consider an electronic commerce application where many companies must communicate. Each of their internal systems may use similar but different document types. To communicate they need to translate their various document types into a common one. An XSLT transformation provides a sophisticated but straightforward way to do so.

To summarize: name notwithstanding, XSLT is more than just a style language. While it can fulfill its original design goal of transforming documents into XSL-FO renditions, it can do far more than that. XSLT can transform XML documents into other XML abstractions, and into other rendered representations as well - such as WordML.

XSLT stylesheets

Most XSLT looks more or less like ordinary XML. Simple XSLT stylesheets are merely a specialized form of XML markup designed for specifying the transformation of other XML documents. You can think of XSLT as just another document type.

A stylesheet that transforms a document into another XML document might have a root element that looks like Example 18-1.

Example 18-1. XSLT stylesheet using XML output elements

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
<xsl:output method="xml"/>
    <!-- template rules go here -->
</xsl:stylesheet>

The root element is xsl:stylesheet.[2] It must have a namespace declaration for XSLT. It makes sense to use the same declaration and xsl: prefix every time. You can also specify the output method to be used by the processor, choosing between XML, HTML and plain text.

The xsl:stylesheet element is usually filled with template rules. The template rules describe how to transform elements in the source document. Of course almost every element type could be processed differently from every other element type so there are many rules in an XSLT stylesheet. Particular elements could even be processed differently if they share a type but have different attributes or occur in a different context.

Using HTML with XSLT

Many XSLT implementations allow transformations from XML into HTML. This is good for serving to today’s mainstream browsers (6.x and up) and the legacy (3.x-5.x) browsers that most websites must still support.

It also takes advantage of many Web designers’ knowledge of HTML. If you format a document using element types from HTML, the page will look to a browser as if it had been created in HTML directly. You can think of this process as a conversion from XML markup to HTML markup. It is a useful way to publish XML documents to the Web.

Because basic HTML is widely understood, we will use HTML element types in most of our examples. We will restrict our usage to only a few HTML types, namely:

  • h1 and h2 element types for top-level and second-level headings;

  • p element type for paragraphs;

  • body element type to contain the document’s content; and the

  • em element type to emphasize a series of characters.

A stylesheet that generates HTML elements might have a root element that looks like Example 18-2.

Example 18-2. XSLT stylesheet using HTML elements

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
<xsl:output method="html"/>
    <!-- template rules go here -->
</xsl:stylesheet>

Rules, patterns and templates

A template rule defines a mapping of parts of a source document into a result document. During XSLT processing every element, character, comment and processing instruction in an XML document is processed by some template rule. Some of them will be handled by template rules that the stylesheet writer created. Others are handled by built-in template rules that are hard-coded into every XSLT processor.

Template rules consist of two parts, the pattern and the template. Be careful with the terminology: a template is not a template rule. The pattern describes which source nodes (elements, textual data strings, comments or processing instructions) should be processed by the rule. The template describes the structure to generate when nodes are found that match the pattern.

In an XSLT stylesheet, a template rule is represented by an xsl:template element.[3] The pattern is the value of the xsl:template element’s match attribute, and the template proper is the element’s content.

Template rules are simple. You do not have to think about the order in which things will be processed, where data is stored or other housekeeping tasks that programming languages usually require you to look after. You just declare what you want the result to look like and the XSLT processor figures out how to make that happen. Because everything is done through declarations we say that XSL is a declarative language.

Creating a stylesheet

XSLT’s processing model revolves around the idea of patterns. Patterns are XPath expressions designed to test nodes. Patterns allow the XSLT processor to choose which elements to apply which style rules to. XSLT’s pattern language is basically XPath with a few extensions and restrictions. Patterns are used in the match attribute of template rules to specify which nodes the rule applies to.

Document-level template rule

Consider a document whose root element-type is book and that can contain title, section and appendix element types. section and appendix elements can contain title, para and list subelements. Titles contain #PCDATA and no subelements. Paragraphs and list items contain emph and #PCDATA. Example 18-3 is a DTD that represents these constraints and Example 18-4 is an example document.

Example 18-3. DTD for book example

<!ELEMENT book (title, (section|appendix)+)>
<!ELEMENT section (title, (para|list)+)>
<!ELEMENT appendix (title, (para|list)+)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT para (#PCDATA|emph)*>
<!ELEMENT emph (#PCDATA)>
<!ELEMENT list (item)+>
<!ELEMENT item (#PCDATA|emph)*>

Example 18-4. Book document instance

<book>
    <title>Chicken Soup for the Chicken's Soul</title>
    <section>
        <title>Introduction</title>
        <para>I've always wanted to write
              this book.</para>
    </section>
</book>

First the XSLT processor would examine the root element of the document. The XSLT processor would look for a rule that applied to books (a rule with a match pattern that matched a book). This sort of match pattern is very simple. Example 18-5 demonstrates.

Example 18-5. Simple match pattern

<xsl:template match="book">
  <!-- describe how books should be transformed -->
</xsl:template>

We can choose any basic structure for the generated book. Example 18-6 shows a reasonable one.

Example 18-6. Generated book structure

<xsl:template match="book">
  <body>
    <h1><!-- handle title --></h1>
    <!-- handle sections -->
    <hr/> <!-- HTML horizontal rule -->
    <h2>Appendices</h2>
    <!-- handle appendices -->
    <hr/>
    <p>Copyright 2004, the establishment.</p>
  </body>
</xsl:template>

The template in this template rule generates a body to hold the content of the document. The tags for the body element are usually omitted in HTML but we’ve generated them here so we can add some attributes to the element later. The body is called a literal result element.

Literal result elements

The XSLT processor knows to treat body as a literal result element that is copied into the output because it is not an XSLT instruction (formally, it is not in the XSLT namespace). Elements in templates that are not part of the XSLT namespace are treated literally and copied into the output. You can see why these are called templates! They describe the form of the result document both by ordering content and by generating literal result elements. If the XSLT processor supports legacy HTML output, and the HTML output method is being used to serialize the result, then it will know to use legacy HTML conventions.

The h1, h2 and hr elements are also literal result elements that will create HTML headings and horizontal rules. As the stylesheet is represented in XML, the specification for the horizontal rule can use XML empty-element syntax. Finally the document has a literal result element and literal text representing the copyright. XSLT stylesheets can introduce this sort of boilerplate text.

Extracting data

The template also has comments describing things we still have to handle: the document’s title, its sections and the appendices.

We can get the data content from the title element with the xsl:value-of instruction. It has a select attribute which is a pattern. If this pattern names a simple element type then it will match a subelement of the current element.

In this case the current element is the book element as that is the element matched by the template rule. Example 18-7 shows what the data extraction would look like.

Example 18-7. Extracting data from a subelement

<h1><xsl:value-of select="title"/></h1>

The apply-templates instruction

The next step is to handle sections and appendices. We could do it in one of two ways. We could either create a new template rule for handling sections or we could handle sections directly in the book template rule.

The benefit of creating a new rule is that it can be used over and over again. Before we create the new rule we should ensure it will get invoked at the right point. We will use a new instruction, xsl:apply-templates. Example 18-8 shows this instruction.

Example 18-8. The xsl:apply-templates instruction

<xsl:apply-templates select="section"/>

The xsl:apply-templates instruction does two important things.

  1. It finds all nodes that match the select attribute pattern.

  2. It processes each of these in turn. It does so by finding and applying the template rule that matches each node.

This important principle is at the heart of XSLT’s processing model.

In this case, the select pattern in the xsl:apply-templates element selects all of the book’s subelements of type section. The xsl:apply-templates instruction always searches out the rule that is appropriate for each of the selected nodes. In this case the xsl:apply-templates instruction always searches out the rule that is appropriate for each of the selected nodes. In this case the xsl:apply-templates instruction will search out a rule that applies to sections. The expanded book template rule is in Example 18-9.

Example 18-9. Handling section elements

<xsl:template match="book">
  <body>
    <h1><xsl:value-of select="title"/></h1>
    <xsl:apply-templates select="section"/>
    <hr/>
    <h2>Appendices</h2>
    <xsl:apply-templates select="appendix"/>
    <p>Copyright 2004, the establishment</p>
  </body>
</xsl:template>

Handling optional elements

Our sample document does not have appendices but the stylesheet should support anything that the DTD or schema allows. Documents of this type created in the future may have appendices.

Our stylesheet generates the title element followed by section elements (in the order that they occurred in the document) followed by appendix elements (also in document order).

If our DTD allowed more than one title subelement in a book element then this stylesheet would generate them all. There is no way for a stylesheet to require that the document have a single title. These sorts of constraints are specified in a DTD or schema.

Our DTD does permit documents to have no appendices. Our “Appendices” title and horizontal rule separating the appendices from the sections would look fairly silly in that case. XSLT provides an instruction called xsl:if that handles this situation. We can wrap it around the relevant parts as shown in Example 18-10.

Example 18-10. Using xsl:if

<xsl:if test="appendix">
  <hr/>
  <h2>Appendices</h2>
  <xsl:apply-templates select="appendix"/>
</xsl:if>

The xsl:if instruction goes within a template. We could drop it into our book template as a replacement for our current appendix handling.

The instruction also contains another template within it. The contained template is only instantiated (generated) if there is some element that matches the pattern exhibited by the test attribute – in this case, an appendix element.

As with the select attribute, the context is the current node. If there is no node that matches the pattern in the test attribute then the entire contained template will be skipped.

There is another instruction called xsl:choose that allows for multiple alternatives, including a default template for when none of the other alternatives match.

Reordering the output

If the DTD had allowed titles, sections and appendices to be mixed together our stylesheet would reorder them so that the title preceded the sections and the sections preceded the appendices.

This ability to reorder is very important. It allows us to use one structure in our abstract representation and another in our rendition. The abstract structure is optimized for editing, validating and processing convenience. The rendered structure is optimized for viewing and navigation.

Reordering is easy when you know exactly the order in which you want elements of various types to be processed. In the case of the body, for example: titles before sections before appendices. But within a section or appendix, reordering is somewhat trickier because we don’t know the complete output order.

That is, we need to process titles before any of the paragraphs or lists, but we cannot disturb the relative order of the paragraphs and lists themselves. Those have to be generated in the document order.

We can solve this fairly easily. In XPath pattern syntax the vertical bar (|) character means “or”. So we can make a rule like the one in Example 18-11.

Example 18-11. The section rule

<xsl:template match="section">
    <h2><xsl:value-of select="title"/></h2>
    <xsl:apply-templates select="para|list"/>
</xsl:template>

This rule forces titles (in our DTD there can be only one) to be handled first and paragraphs and lists to be processed in the order that they are found. The rules that are defined for paragraphs and lists will automatically be selected when those types of element appear. We’ll create those rules next.

Data content

Next we can handle paragraphs. We want them each to generate a single HTML element. We also want them to generate their content to populate that element in the order that the content occurs, not in some order pre-defined by the template.

We need to process all of the paragraph’s subnodes. That means that we cannot just handle emph subelements. We must also handle ordinary character data. Example 18-12 demonstrates this.

Example 18-12. Paragraph rule

<xsl:template match="para">
    <p><xsl:apply-templates select="node()"/>
    </p>
</xsl:template>

As you can see, the rule for paragraphs is very simple. The xsl:apply-templates instruction handles most of the work for us automatically. The select attribute matches all nodes: element nodes, text nodes, etc. If it encounters a text node it copies it to the result; that is a default rule built into XSLT. If it encounters a subelement, it processes it using the appropriate rule.

XSLT handles much of the complexity for us but we should still be clear: transformations will not always be this easy. These rules are so simple because our DTD is very much like HTML. The more alike the source and result DTDs the simpler the transformation will be. It is especially helpful to have a very loose or flexible result DTD. HTML is perfect in this regard.

Handling inline elements

The rule for emph follows the same basic organization as the paragraph rule. Mixed content (i.e. character-containing) elements often use this organization. The HTML element-type name is em (Example 18-13). Note that in this case we will use an abbreviated syntax for the xsl:apply-templates element: Because the select attribute defaults to node(), we can leave it out.

Example 18-13. Handling emphasis

<xsl:template match="emph">
    <em><xsl:apply-templates/></em>
</xsl:template>

List items also have mixed content, so we should look at the rules for lists and list items next. They are in Example 18-14.

Example 18-14. List and item rules

<xsl:template match="list">
    <ol>
       <xsl:apply-templates/>
    </ol>
</xsl:template>
<xsl:template match="item">
    <li><xsl:apply-templates/></li>
</xsl:template>

The rules in Example 18-13 and Example 18-14 work together. When a list is detected the literal result element is processed and an ol element is generated. It will contain a single li element for each item. Each li will in turn contain text nodes (handled by the default rule) and emph (handled by the emph rule).

Sharing a template rule

We still need a template rule for appendices. If we wrote out the rule for appendices we would find it to be identical to sections. We could just copy the sections rule but XSLT has a more elegant way. We can amend our rule for sections to say that the rule applies equally to sections or appendices. Example 18-15 demonstrates.

Example 18-15. The rule in Example 18-11 revised to handle appendices as well as sections

<xsl:template match="section|appendix">
    <h2><xsl:value-of select="title"/></h2>
    <xsl:apply-templates select="para|list"/>
</xsl:template>

Final touches

We now have a complete stylesheet but it is rather basic. We might as well add a background color to beautify it a bit. HTML allows this through the bgcolor attribute of the body element. We will not go into the details of the HTML color scheme but suffice to say that Example 18-16 gives our document a nice light purple background.

Example 18-16. Adding a background color

<xsl:template match="book">
  <body bgcolor="#FFDDFF">
    <!-- Handling of body content is unchanged -->
    ...
  </body>
</xsl:template>

There is also one more detail we must take care of. We said earlier that the more flexible a document type is the easier it is to transform to. Even though HTML is pretty flexible it does have one unbreakable rule. Every document must have a title element, but “title” means something different in the HTML vocabulary from what it does in our book DTD.

We’ve handled the title element from the source as a heading, but in HTML the title shows up in the window’s title bar, in the bookmark list and in search engine result lists. We need the document’s title to appear as both the HTML title and as an HTML heading element. Luckily XSLT allows us to duplicate data.

With these additions our stylesheet is complete! It is shown in Example 18-17.

Example 18-17. Complete stylesheet

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
<xsl:output method="html"/>

<xsl:template match="book">
  <body bgcolor="#FFDDFF">
    <title><xsl:value-of select="title"/></title>
    <h1><xsl:value-of select="title"/></h1>
    <xsl:apply-templates select="section"/>
    <hr/>
    <xsl:if test="appendix">
      <hr/>
      <h2>Appendices</h2>
      <xsl:apply-templates select="appendix"/>
    </xsl:if>
    <p>Copyright 2004, the establishment</p>
  </body>
</xsl:template>

<xsl:template match="para">
    <p><xsl:apply-templates/></p>
</xsl:template>

<xsl:template match="emph">
    <em><xsl:apply-templates/></em>
</xsl:template>

<xsl:template match="list">
    <ol>
       <xsl:apply-templates/>
    </ol>
</xsl:template>

<xsl:template match="item">
    <li><xsl:apply-templates/></li>
</xsl:template>

<xsl:template match="section|appendix">
    <xsl:apply-templates select="title"/>
    <xsl:apply-templates select="para|list"/>
</xsl:template>
</xsl:stylesheet>

As you can see, simple transformations can be quite simple to specify in XSLT – evidence of the language’s good design. The important thing to keep in mind is that the basic XSLT processing model is based on template rules, patterns and templates. Flow of control between rules is handled by special instructions.

Top-level instructions

XSLT also allows you to do more complex things. It supports all of XPath, sophisticated selections, stylesheet reuse and many other advanced features. We will introduce a few of these in this section.

Top-level instructions are those that go directly in the xsl:stylesheet element. They do not apply to any particular template rule but rather declare behaviors, variables and other things that affect the entire stylesheet. Except for xsl:import instructions, which we’ll describe shortly, the order of top-level statements is not important.

Combining stylesheets

There are two ways to combine stylesheets: inclusion and import.

Including other stylesheets

The xsl:include instruction includes another stylesheet. Stylesheets may not include themselves directly or indirectly. The instructions in an included stylesheet are treated exactly as if they had been typed directly in the including stylesheet. They are not second-class in any sense. Example 18-18 demonstrates the inclusion of other stylesheets through both absolute and relative URIs.

Example 18-18. Including another stylesheet

<xsl:include href="http://.../currency.xsl"/>
<xsl:include href="bonds.xsl"/>

Importing from other stylesheets

Importing is a little bit different from including. Just as in the real world, there are restrictions on imports! In the XSLT context that means imports are second-class. Imported rules only take effect when no rule in the main stylesheet matches. Also, import statements earlier in the document take precedence over later ones.

Import instructions must go at the top of a stylesheet, preceding any other top-level instructions and the xsl:template elements. A stylesheet must not directly or indirectly import itself. Example 18-19 demonstrates the importation of other stylesheets through both absolute and relative URIs.

Example 18-19. Importing another stylesheet

<xsl:import href="http://.../stocks.xsl"/>
<xsl:import href="credit-cards.xsl"/>

Whitespace handling

Whitespace nodes are ordinary text nodes that happen to have only whitespace (tab, space, newline) characters in them.

In machine-to-machine applications, whitespace nodes are usually irrelevant. Even in publishing applications, some whitespace is not important for processing. A blank line between two section elements is just intended to make the source XML easier to read. It is not intended to affect what is seen by the ultimate readers of the rendered document.

XSLT has a feature that allows you to strip out these whitespace-only nodes based on the elements in which they occur. The xsl:strip-space instruction strips space from elements of specified types in the source document. Example 18-20 shows how you would strip space from address and date elements.

Example 18-20. Stripping space

<xsl:strip-space elements="address date"/>

In some vocabularies, all element types are so-called space-stripping. You can accomplish this by using an asterisk in the xsl:strip-space instruction (Example 18-21

Example 18-21. Strip space from all elements

<xsl:strip-space elements="*"/>

If a vocabulary has only a few non-whitespace stripping elements (whitespace-preserving elements), you can selectively override the blanket stripping statement with the xsl:preserve-space instruction. By default, whitespace is preserved.

Output descriptions

The xsl:output instruction sets various options that control what the stylesheet should generate as output. The main attribute in the instruction is the method attribute, which typically takes a value like “xml”,“html” or “text”.

“xml” is appropriate for (surprise!) generating XML; it is the default. “html” uses html conventions for empty-elements, processing instructions and similar constructs. The “text” output is useful when you want to generate plain text without the XSLT processor representing delimiter characters such as less-than signs (<) as &lt;, and so forth.

Other attributes can control whether the output is indented for “pretty printing”, what character encoding to use, whether to add an XML declaration and/or document type declaration and other (even more obscure) output options. Most XSLT stylesheets will not need to change these options from their defaults.

But if you find that the output of your stylesheet is not quite what you would expect, then xsl:output may have the answer for you.

Numeric formats

The xsl:decimal-format instruction allows you to describe how decimal numbers will be printed by your stylesheet. For instance, you can use this to change the character that separates the decimals from the integral part of the number. You could set that option to period for North Americans and comma for Europeans.

Other options allow you to change the “grouping-separator” between the billions, millions and thousands and to choose characters or strings to represent “infinity”, “minus”, “percent”, “per-mille” (per thousand), “the zero digit” and “Not a number”. The latter is used for error handling.

Attribute sets

xsl:attribute-set allows you to define a reusable set of attributes. If you have several different types of images that must share certain attributes then it is more efficient to define those in an attribute set than to repeat them all in each template rule. Example 18-22 demonstrates the basic idea.

Example 18-22. Reusable set of attribute values

<xsl:attribute-set name="big-image">
    <xsl:attribute name="width">500px</xsl:attribute>
    <xsl:attribute name="height">500px</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="small-image">
    <xsl:attribute name="width">100px</xsl:attribute>
    <xsl:attribute name="height">100px</xsl:attribute>
</xsl:attribute-set>

... in a template ...
<img xsl:use-attribute-sets="big-image">

Namespace alias

Just as xsl:output helps you to solve the problem of how to treat a less-than sign as an ordinary data character, xsl:namespace-alias helps you to treat a namespace prefixed literal result element as just a literal result element, even if the namespace happens to be XSLT! This sounds strange but it could happen if you were writing an XSLT stylesheet that generates an XSLT stylesheet. Needless to say, this is not a common situation so we will not dwell on it further.

Keys

Keys are a performance-enhancement concept borrowed from the database world. Their main use is to provide a (possibly) faster way to reference elements by the values of their attributes or subelements. You get to decide which attribute or element values form the key by declaring it, as shown in Example 18-23.

Example 18-23. Declaring a key

<xsl:key name="employees-by-ssn"
         match="employee"
         use="social-security"/>

Keys don’t let you do anything that can’t be done with normal XPath addressing, which is why we’re not explaining them in detail. Their major benefit is to allow the XSLT processor to build a lookup table to attempt to speed up keyed references. Whether the attempt succeeds depends on the number of keys, how often they are referenced, and the complexity of the XPath expressions they replace.

Keys can also simplify a stylesheet by letting you use simple key names in place of possibly complex XPath expressions. Not all XSLT processors support keys.

Variables and parameters

XSLT variables and parameters are closely related in that both involve replacing a name with an associated value (much like an XML entity).

Variables

An XSLT variable is a value that a stylesheet creator stores away for use in some other part of the stylesheet. A top-level variable is one defined outside any template rule. The value is automatically available for use in any template. For instance a variable could hold the company name. The value that the variable holds could even be extracted from the input XML document. Example 18-24 demonstrates.

Example 18-24. Defining a variable

<xsl:variable name="company-name" select="/doc/creator/company"/>

Variables can be referred to in XPath expressions by preceding the variable name with a dollar-sign ($). Example 18-25 demonstrates.

Example 18-25. Referencing a variable

<xsl:value-of select="$company-name"/>

Parameters

An XSLT parameter is just like a variable except that the value can be overridden. How it would be overridden depends on your XSLT implementation. Command-line XSLT transformation engines typically use command-line options. Graphical environments might use options in a graphical user interface. In other words, parameters are user options that change the stylesheet’s behavior. They are declared and referenced just as variables are. Example 18-26 demonstrates.

Example 18-26. Defining a parameter

<xsl:param name="company-name" select="/doc/creator/company"/>

The select attribute of a parameter is used as a default value. If the user fails to supply a parameter, the default value is used when the stylesheet is processed.

It is also possible to define template rules that have parameters. In that case, the parameters are only available within that template. Template rule parameters are passed not from the user, but from other templates. For instance a template for a chapter might use a parameter to pass the chapter number to a template rule for a section. That way the section number could be derived from the chapter number (e.g. section number 5.4 within Chapter 5).

Extending XSLT

XSLT permits customized extensions (the “X” in “XSLT”) to be supported by an XSLT processor.

The XSLT language has a mechanism that allows you to call into a component written in any programming language. You could refer to a Java class file, Python program, Perl script or an ActiveX control. You could even embed a small script from a scripting language such as Javascript or Python. The script can be defined right in your stylesheet!

Referencing XSLT stylesheets

There is a W3C Recommendation that specifies how XML documents should refer to their stylesheets. Here is the relevant text:

Example 18-1. The xml-stylesheet processing instruction

The xml-stylesheet processing instruction is allowed anywhere in the prolog of an XML document. The processing instruction can have pseudo-attributes href (required), type (required), title (optional), media (optional), charset (optional).

These are called pseudo-attributes because, although they use attribute syntax, they do not describe properties of an element. The only real syntactic difference between pseudo-attributes and attributes is that you must use pseudo-attributes in the order they are defined. You can use attributes in any order.

The most important pseudo-attributes for this processing instruction are href, which supplies a URI for the stylesheet, and type, which says whether the stylesheet is in XSLT, DSSSL, CSS, or some other stylesheet language.

Example 18-27 is a sample stylesheet processing instruction (PI).

Example 18-27. Stylesheet PI

<?xml-stylesheet href="http://www.xmlbooks.com/memo.xsl"
                 type="text/xsl"?>

You can provide multiple PIs to allow for different output media or stylesheet language support. You could, for example, have different stylesheets for print (with footnotes and page breaks), online (with clickable links), television (large text and easy scroll controls) and voice (read aloud using inflection to render emphasis). In such cases, you would want to specify a media pseudo-attribute and possibly a title that the browser might use when offering a list of stylesheet choices. Example 18-28 demonstrates this.

Example 18-28. Alternative stylesheets

<?xml-stylesheet rel=alternate
                href="mystyle1.xsl"
                title="Fancy"
                media="print"
                type="text/xsl"?>
<?xml-stylesheet
                rel=alternate
                href="mystyle2.css"
                title="Simple"
                media="online"
                type="text/css"?>
<?xml-stylesheet
                rel=alternate
                href="mystyle2.aur"
                title="Aural"
                media="voice"
                type="text/aural"?>


[1] The one we recommended is Definite XSLT and XPath by Ken Holman, published in this series.

[2] The space also allows the root element to be called xsl:transform, presumably for the benefit of people with no style sense!

[3] It would have been clearer had they called it an xsl:template-rule element, but they didn’t.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.103.28