Fallback Processing Extension Elements, Extension Functions, and Fallback Processing

page 155 xsl:for-each select=bookchapter h1xsl:value-of select=titleh1 xsl:apply-templates select=para xsl:for-each body html xsl:if xsl:fallback redirect:write xsl:for-each xsl:template xsl:template match=para pxsl:apply-templates select=|textp xsl:template xsl:stylesheet In our example, we only invoke the fallback processing once. This approach assumes that if somethings wrong with the extension, it will fail the first time and be completely inaccessible. Using xsl:fallback , we know that the contents of the xsl:fallback element will be invoked if anything goes wrong when the stylesheet processor attempts to use an extension element. If youd like more complete control over fallback processing, you can use the element-available and function-available functions as we did in our earlier example.

8.2 Extending the Saxon Processor

Michael Kays excellent Saxon processor also provides an extension mechanism. One of the nice features of Saxons extensibility mechanism is that you can implement your own sort functions. When we discussed the xsl:sort element a couple of chapters ago, we mentioned that it has a lang attribute that defines the language of the things being sorted. While Xalan doesnt currently support this attribute although by the time youre reading this, it might, Saxon lets you create your own extension function to handle the sorting. Your extension function must extend the com.icl.saxon.sort.TextComparer class. Heres a sample XML document well use to illustrate this function: ?xml version=1.0? wordlist wordcampoword wordlunaword wordciudadword wordllavesword wordchihuahuaword wordarrozword wordlimonadaword wordlist This document contains Spanish words that are sorted differently than they would be in English. In Spanish, ch and ll are separate letters that sort after c and l, respectively. Well write a stylesheet that uses three xsl:template s to illustrate how our extension function works. Heres the stylesheet: ?xml version=1.0? xsl:stylesheet version=1.0 xmlns:xsl=http:www.w3.org1999XSLTransform xsl:output method=text indent=no xsl:strip-space elements= xsl:variable name=newline xsl:text xsl:text xsl:variable xsl:template match= xsl:value-of select=newline xsl:apply-templates select=wordlist mode=unsorted page 156 xsl:apply-templates select=wordlist mode=default xsl:apply-templates select=wordlist mode=Spanish xsl:template xsl:template match=wordlist mode=unsorted xsl:textWord list - unsorted:xsl:text xsl:value-of select=newline xsl:for-each select=word xsl:value-of select=. xsl:value-of select=newline xsl:for-each xsl:value-of select=newline xsl:template xsl:template match=wordlist mode=default xsl:textWord list - sorted with default rules:xsl:text xsl:value-of select=newline xsl:for-each select=word xsl:sort select=. xsl:value-of select=. xsl:value-of select=newline xsl:for-each xsl:value-of select=newline xsl:template xsl:template match=wordlist mode=Spanish xsl:textWord list - sorted with Spanish rules:xsl:text xsl:value-of select=newline xsl:for-each select=word xsl:sort select=. lang=es xsl:value-of select=. xsl:value-of select=newline xsl:for-each xsl:value-of select=newline xsl:template xsl:stylesheet When we run the stylesheet against our document, it invokes the three templates with three different mode s. One template simply lists the word elements as they appear in the original document, the second sorts the word elements using the default sorting sequence, and the third sorts the word elements using the traditional rules of Spanish sorting. Refreshingly enough, the code that implements the sorting function is simple. Heres the entire listing: package com.icl.saxon.sort; import java.text.ParseException; import java.text.RuleBasedCollator; import java.util.Locale; public class Compare_es extends TextComparer { private static String smallnTilde = new String\u00F1; private static String capitalNTilde = new String\u00D1; private static String traditionalSpanishRules = a,A b,B c,C + ch, cH, Ch, CH + d,D e,E f,F + g,G h,H i,I j,J k,K l,L + ll, lL, Ll, LL + m,M n,N + + smallnTilde + , + capitalNTilde + + o,O p,P q,Q r,R + s,S t,T u,U v,V w,W x,X + y,Y z,Z; private static RuleBasedCollator rbc = null; static { try { rbc = new RuleBasedCollatortraditionalSpanishRules;