xsl:fallback


The <xsl:fallback> instruction is used to define processing that should occur if no implementation of its parent instruction is available.

Changes in 2.0

None.

Format

 <xsl:fallback>    <!-- Content: sequence-constructor --> </xsl:fallback> 

Position

<xsl:fallback> is an instruction. It is generally used within a sequence constructor. However, some new XSLT 2.0 instructions ( <xsl:analyze-string> , <xsl: next -match> ) allow an <xsl:fallback> element as a child even though they do not contain a sequence constructor. This is to allow fallback behavior to be defined for use when these instructions are encountered by an XSLT 1.0 processor.

Attributes

None.

Content

A sequence constructor.

Effect

There are two circumstances where <xsl:fallback> can be useful:

  • In a stylesheet that uses XSLT features defined in version 2.0, to indicate what should happen if the stylesheet is used with an XSLT 1.0 processor. For example, the draft XSLT 2.0 specification introduces the new instruction <xsl:result-document> . If you want to use the <xsl:result-document> instruction in a stylesheet, and also want to specify what an XSLT 1.0 processor that doesn't understand this instruction should do, you can define the required behavior using <xsl:fallback> . XSLT 1.0 was carefully designed with extensibility in mind, so every XSLT 1.0 processor should implement this fallback behavior correctly even though the new XSLT 2.0 instructions were not defined at the time the processor was written.

  • In a stylesheet that uses extension elements provided by a vendor, by the user , or by a third party, to indicate what should happen if the stylesheet is used with an XSLT processor that does not support these extensions.

If the <xsl:fallback> instruction is encountered in a sequence constructor that the processor can evaluate normally, it is ignored, along with its contents.

An instruction (as distinct from a literal result element) is an element that occurs in a sequence constructor and is:

  • either in the XSLT namespace

  • or in a namespace designated as an extension namespace by its inclusion in the [xsl:]extension-element-prefixes attribute of the element itself or a containing element. This attribute must be in the XSLT namespace if the element containing it is not in the XSLT namespace, and vice versa.

If an instruction is recognized by the XSLT processor, it is evaluated. The standard doesn't define exactly what "recognized by the XSLT processor" means. Typically it means that either the instruction is a vendor-specific extension implemented by that vendor, or it is a user-defined extension that has been installed or configured according to the instructions given by the vendor. It is also quite permissible for one vendor, say Oracle, to recognize extensions defined by another vendor, say Microsoft.

If an instruction is not recognized by the XSLT processor, the action taken by an XSLT 2.0 processor is as follows :

  • For an element in the XSLT namespace, if the effective version is «2.0 » or less, an error is reported . If the effective version is higher than «2.0 » , fallback processing is invoked.

  • For an extension element, fallback processing is invoked.

Similarly, an XSLT 1.0 processor invokes fallback processing when it sees an instruction in the XSLT namespace if the effective version is «2.0 » (or indeed, any value other than «1.0 » ).

The effective version is the value of the [xsl:]version attribute on the nearest enclosing element that has such an attribute (the attribute must be in the XSLT namespace if the element is not in the XSLT namespace, and vice versa). The value is a decimal number (for example «2.3 » , «10.852 » , or «17 » , and it is compared numerically . The idea is that a stylesheet, or a portion of a stylesheet, that uses facilities defined in some future XSLT version, 2.1 (say), should be given an effective version of «2.1 » .

Note that while XSLT 2.0 allows the version attribute to appear on any element in the XSLT namespace, XSLT 1.0 allowed it only on the <xsl:stylesheet> element. This means that if you want an XSLT 1.0 processor to invoke fallback behavior on a stylesheet that uses XSLT 2.0 features, you must either specify «version="2.0" » on the <xsl:stylesheet> element, or specify «xsl:version="2.0" » on a containing literal result element. In practice, it is a good idea to put the templates and other declarations that depend on XSLT 2.0 in a separate stylesheet module, and label that module with «version="2.0" » on the <xsl:stylesheet> element.

Fallback processing means that if the unknown instruction has an <xsl:fallback> child element, the <xsl:fallback> instruction is evaluated; otherwise , an error is reported. If there is more than one <xsl:fallback> instruction, they are all evaluated.

<xsl:fallback> is concerned only with fallback behavior for instructions within sequence constructors. Top-level declarations that the implementation doesn't recognize are simply ignored, as are unrecognized elements in another context (for example, an unrecognized child of an <xsl:choose> or <xsl:call-template> instruction).

Note that both the [xsl:]version attribute and the [xsl:]extension-element-prefixes attribute apply only within the stylesheet module in which they occur: They do not apply to stylesheet modules incorporated using <xsl:include> or <xsl:import> .

Usage

The <xsl:fallback> mechanism allows a stylesheet to be written that behaves sensibly with XSLT processors that handle different versions of XSLT. This is motivated by the experience of Web developers with HTML, and especially by the difficulty of writing Web pages that work correctly on different browsers. The design aimed to cater for a world in which some browsers would include an XSLT 2.0 processor and others would provide an XSLT 1.0 processor; in this situation, it would become necessary to write stylesheets that would work with either.

Similarly, it is very likely that each vendor of an XSLT processor (or each browser vendor) will add some bells and whistles of their own-indeed, this has already happened with XSLT 1.0. For server-side stylesheet processing you might be prepared to use such proprietary extensions and thus lock yourself into the products of one vendor; but more likely, you want to keep your stylesheets portable. The <xsl:fallback> mechanism allows you to do this by defining within any proprietary extension element what the XSLT processor should do if it doesn't understand it. This might be, for example:

  • Do nothing, if the behavior is inessential, such as keeping statistics.

  • Invoke an alternative implementation that achieves the same effect.

  • Output fallback text to the user explaining that a particular facility cannot be offered and suggesting how they should upgrade.

An alternative way of defining fallback behavior when facilities are not available is to use the element-available() function, and to avoid executing the relevant parts of a stylesheet. This function is described in Chapter 7, page 542. The two mechanisms have overlapping functionality, so use whichever you find most convenient .

Examples

The two examples that follow illustrate the principal use cases for <xsl:fallback> : creating stylesheets that are forwards compatible across XSLT versions, and creating stylesheets that use vendor extensions while maintaining portability. The third example is not actually an example of <xsl:fallback> at all: It shows another method of achieving fallback behavior when <xsl:fallback> won't do the job.

Example 1: XSLT Forwards Compatibility

The following example shows a stylesheet written to exploit a hypothetical new XSLT feature in version 6.1 of the standard that inserts a document identified by URI straight into the result tree. The stylesheet is written so that if this feature is not available, the same effect is achieved using existing facilities.

  <xsl:template match="boilerplate" version="6.1">   <div id="boilerplate">   <xsl:copy-to-output href="boilerplate.xhtml">   <xsl:fallback>   <xsl:copy-of select="document('boilerplate.xhtml')"/>   </xsl:fallback>   </xsl:copy-to-output>   </div>   </xsl:template>  

Example 2: Vendor Portability

Writing a stylesheet that uses vendor extensions but is still portable is not particularly easy, but the mechanisms are there to achieve it, especially in the case where several vendors provide similar extensions but in slightly different ways.

For example, several XSLT 1.0 processors ( certainly xt, Saxon, and Xalan) provide a feature to generate multiple output files from a single stylesheet. With XSLT 2.0 this popular facility has made it into the XSLT standard, but before that happened, each product had to invent its own syntax. If you want to write a stylesheet that uses the XSLT 2.0 facility when it is available, but with fallback implementations for these three products, you could do it like this:

  <xsl:template match="preface">   <a href="preface.html" xsl:version="2.0"   xmlns:saxon="http://icl.com/saxon"   xmlns:xt="http://www.jclark.com/xt"   xmlns:xalan="com.lotus.xsl.extensions.Redirect"   xsl:extension-element-prefixes="saxon xt xalan">   <xsl:result-document href="preface.html">   <xsl:call-template name="write-preface"/>   <xsl:fallback>   <saxon:output file="preface.html">   <xsl:call-template name="write-preface"/>   <xsl:fallback/>   </saxon:output>   <xt:document href="preface.html">   <xsl:call-template name="write-preface"/>   <xsl:fallback/>   </xt:document>   <xalan:write file="preface.html">   <xsl:call-template name="write-preface"/>   <xsl:fallback/>   </xalan:write>   </xsl:fallback>   </xsl:result-document>   Preface</a>   </xsl:template>  

Hopefully this little nightmare will disappear once XSLT 2.0 is finalized and becomes widely implemented. However, by then the vendors, no doubt, will have thought of other good ideas to include as nonstandard extensions.

Example 3: Temporary Trees

This example doesn't actually use <xsl:fallback> ; it's an example of where the same effect needs to be achieved by different means.

One of the most important new features introduced in XSLT 2.0 is the ability to process a tree-valued variable as a document in its own right, using facilities such as XPath path expressions and <xsl:for-each> . The following code, which is perfectly legal in XSLT 2.0, will be flagged as an error by an XSLT 1.0 processor:

  <xsl:variable name="us-states">   <state abbr="AZ" name="Arizona"/>   <state abbr="CA" name="California"/>   <state abbr="NY" name="New York"/>   </xsl:variable>   ...   <xsl:value-of select="$us-states/state[@abbr='CA']/@name"/>  

The change to make this legal in XSLT 2.0 involves no new instructions, so it isn't possible to write an <xsl:fallback> template that defines what an XSLT 1.0 processor should do with this code: There's no suitable instruction to contain it. The only way of defining fallback behavior in this case is to test the XSLT version using the system-property () function. The following stylesheet will work with both XSLT 1.0 and XSLT 2.0. This accesses a lookup table defined as a global variable in the stylesheet. With a 2.0 processor, it accesses the variable containing the lookup table directly. With a 1.0 processor, it does it by using the «document('') » construct to read the stylesheet as a secondary input document.

  <xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:variable name="us-states">   <state abbr="AZ" name="Arizona"/>   <state abbr="CA" name="California"/>   <state abbr="NY" name="New York"/>   </xsl:variable>   <xsl:param name="state" select="'AZ'"/>   <xsl:variable name="is-1.0"   select="system-property('xsl:version')=1.0"/>   <xsl:variable name="lookup-table-1.0"   select="document('')/*/xsl:variable[@name='us-states']"/>   <xsl:template match="/">   <xsl:choose>   <xsl:when test="$is-1.0">   <xsl:value-of select="$lookup-table-1.0/state[@abbr=$state]/@name"/>   </xsl:when>   <xsl:otherwise>   <xsl:value-of select="$us-states/state[@abbr=$state]/@name"/>   </xsl:otherwise>   </xsl:choose>   </xsl:template>   </xsl:stylesheet>  

I used «version="2.0" » on the <xsl:stylesheet> element here, but in fact «version="1.0" » works just as well, because there is nothing in the forwards compatibility rules that relates to this situation, where the syntax is legal at both versions but the runtime behavior is an error for version 1.0. In theory, an XSLT 1.0 processor could legitimately reject the above stylesheet at compile time, regardless of whether it specifies «version="1.0" » or «version="2.0" » , but fortunately the XSLT 1.0 processors that I've tried accept it without quibble.

In this example I used the standard document() function to provide fallback processing that works with all XSLT 1.0 processors. In more complex examples, the fallback processing might need to use vendor extensions such as Microsoft's msxml:node-set() extension function. In this situation different fallback mechanisms would be needed for different processors.

See Also

Extensibility in Chapter 3, page 128

Literal Result Elements in Chapter 3, page 106

element-available() function in Chapter 7, page 542

system-property() function in Chapter 7, page 581




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

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