XSLT for Dummies

 
Chapter 16 - Extending XSLT
XSLT For Dummies
by Richard Wagner
Hungry Minds 2002
  

As I said from the get-go, because extension elements or functions are not part of the XSLT standard, their support depends entirely on the XSLT processor vendor. The obvious problem that can then surface is that, when you try to run your extension-laden stylesheet, the XSLT processor youre using may not support the extensions youre using. For example, if you try to run the saxon:while example earlier in the chapter using msxsl , you get a processing error saying that saxon:while is an unrecognized element.

Rather than allowing this error to occur, you need a fallback strategy, in the event that the stylesheet is run by a processor that doesnt support the extension. As I discuss in the following sections, you can add a fallback plan to your stylesheet and test for the support of extension elements or functions before they are processed as part of the stylesheet.

Testing extension elements

For extension elements, the first way in which you can handle unsupportive processors is to use the xsl:fallback element, which you can embed inside the extension element youre using. If the processor runs the extension successfully, then the xsl:fallback instruction is simply ignored. But suppose all heck breaks loose and the processing engine doesnt recognize the extension. When this event occurs, the processor executes the instructions provided inside xsl:fallback . If you add xsl:fallback to the saxon:while stylesheet shown earlier in this chapter, the stylesheet looks like this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon"> <xsl:template match="/"> <xsl:variable name="idx" saxon:assignable="yes" select="1"/> <saxon:while test="$idx &lt; 11"> The value of idx is <xsl:value-of select="$idx"/> <saxon:assign name="idx" select="$idx+1"/> <xsl:fallback> <xsl:message terminate="yes">XSLT processor does not support saxon:while extension.</xsl:message> </xsl:fallback> </saxon:while> </xsl:template> </xsl:stylesheet>

In this case, if the processor doesnt support saxon:while , then an xsl:message instruction is nestled inside xsl:fallback . When encountered , the xsl:message instruction sends its contents as a template to the processor and its terminate attribute specifies whether or not the processor should stop processing. It is up to the processor to determine how it wants to handle the xsl:message template; some may output it in the result document, while others display a message box with the template contents. Therefore, if the xsl:fallback instruction is executed, you know the processor does not support the extension.

A second way to determine whether or not an element is supported is by using the element-available() built-in function. This function allows you to test an extension element so that you can determine whether or not it is supported before you try to call it. The typical scenario is to test it inside an xsl:choose instruction, as shown here:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon"> <xsl:template match="/"> <xsl:variable name="idx" saxon:assignable="yes" select="1"/> <xsl:choose> <xsl:when test="element-available('saxon:while')"> <saxon:while test="$idx &lt; 11"> The value of idx is <xsl:value-of select="$idx"/> <saxon:assign name="idx" select="$idx+1"/> </saxon:while> </xsl:when> <xsl:otherwise> Sorry, Charlie. No support here for while looping. </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>

In this example, xsl:when tests to determine whether saxon:while is an element that the processor can use. If so, then the processor executes the contents of saxon:while . If not, the xsl:otherwise element is used instead, adding the "Sorry, Charlie" literal text to the result document.

 Tip   For most purposes, the choice of using xsl:fallback versus element-available() is personal preference. However, the one case in which element-available() is the more powerful option is when you want to test for multiple extension elements and, depending on which element is available, add a different result to the output.

For example, I can add an extra xsl:when to the preceding stylesheet to test to see if msxsl:script is available if saxon:while is not. The xsl:choose instruction would be changed to:

<xsl:choose> <xsl:when test="element-available('saxon:while')"> <saxon:while test="$idx &lt; 11"> The value of idx is <xsl:value-of select="$idx"/> <saxon:assign name="idx" select="$idx+1"/> </saxon:while> </xsl:when> <xsl:when test="element-available('msxsl:script')"> <!-- run a script --> </xsl:when> <xsl:otherwise> Sorry, Charlie. No support here for while looping. </xsl:otherwise> </xsl:choose>

When this stylesheet is applied, the XSLT processor first tests to see whether saxon:while is available. If not, then msxsl:script is tested . And if it is not available too, then xsl:otherwise is chosen .

Testing extension functions

Extension functions can be evaluated in a way eerily similar to the element-available() function described in the preceding section. The function-available() built-in function tests whether the processor supports a function. For example:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date"> <xsl:template match="/"> <xsl:choose> <xsl:when test="function-available('date:time')"> <xsl:value-of select="date:time()"/> </xsl:when> <xsl:otherwise> What do you think I am? A Timex? </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>

In this example, the xsl:when instruction checks to see if the date:time() function is available. If the test returns true, then the function is run. But if not, then the XSLT processor uses the xsl:otherwise element and outputs its contents to the result document.

 Tip   Even if you use a single XSLT processor, it is good programming practice to add fallback code if you use extension elements in your stylesheets. Doing so helps ensure that your stylesheets produce exactly the results you intend.

  
 
 
2000-2002    Feedback

Категории