The document Function and Sorting

page 127 What makes this process slightly challenging is the fact that were sorting on one thing the value of the state element, then invoking xsl:apply-templates against the purchase- order ancestor of the state element. We simply used the ancestor:: axis to do this. Figure 7-2 shows our output document, sorted by the value of the state element in each purchase order.

7.4.2 Implementing Lookup Tables

We mentioned earlier that calling the document function with an empty string enabled us to access the nodes in the stylesheet itself. We can use this behavior to implement a lookup table. As an example, well create a lookup table that replaces an abbreviation such as ME with Maine . We can then use the value from the lookup table as the sort key. More attentive readers might have noticed in our previous example that although the abbreviation MA does indeed sort before the abbreviation ME , a sorted list of the state names themselves would put Maine abbreviation ME before Massachusetts abbreviation MA . First, well create our lookup table. Well use the fact that a stylesheet can have any element as a top-level element, provided that element is namespace-qualified to distinguish it from the xsl: namespace reserved for stylesheets. Heres the namespace prefix definition and part of the lookup table that uses it: ?xml version=1.0? xsl:stylesheet version=1.0 xmlns:xsl=http:www.w3.org1999XSLTransform xmlns:states=http:new.usps.comcgi-binuspsbvscriptscontent.jsp?D=10090 states:name abbrev=ALAlabamastates:name states:name abbrev=ALAlabamastates:name states:name abbrev=AKAlaskastates:name states:name abbrev=ASAmerican Samoastates:name -- Most state abbreviations removed to keep this listing brief... -- states:name abbrev=MEMainestates:name states:name abbrev=MHMarshall Islandsstates:name states:name abbrev=MDMarylandstates:name states:name abbrev=MAMassachusettsstates:name The namespace mapped to the states prefix is the URL for the official list of state abbreviations from the United States Postal Service. To look up values in our table, well use the document function to return the root node of our stylesheet, then well look for a states:name element with a abbrev attribute that matches the value of the current state element in the purchase order were currently processing. Heres the somewhat convoluted syntax that performs this magic: body h3Selected Purchase Orders - iSorted by stateih3 xsl:for-each select=documentreportpofilenamepurchase-ordercustomeraddressstate xsl:sort select=documentstates:name[abbrev=current] xsl:apply-templates select=ancestor::purchase-order xsl:for-each body Notice that we use the document function twice; once to open the document referred to by the filename element, and once to open the stylesheet itself. We also need to discuss the XPath expression in the select attribute of the xsl:sort element. There are four significant parts to this expression: document Returns the root node of the current stylesheet. page 128 Indicates that what follows must be a top-level element of the stylesheet. This syntax starts at the root of the document, then has a single element. The elements name can be anything. For our current stylesheet, we could have written the XPath expression like this: select=documentxsl:stylesheetstates:name[abbrev=current] Because the root element of a stylesheet can be either xsl:stylesheet or xsl:transform , its better to use the asterisk. states:name Indicates a name element combined with a namespace prefix that maps to http:new.usps.comcgi-binuspsbvscriptscontent.jsp?D=10090 . If we were referencing elements in another document, the prefix wouldnt have to be states ; it could be anything, as long as it mapped to the same string. [abbrev=current] Means that the abbrev attribute of the current states:name element has the same value as the current node. We have to use the XSLT current function here because we want the current node, not the context node. Inside the predicate expression, the current node is the state element we process, while the context node is the states:name element that contains the abbrev attribute we evaluate. Figure 7-3 shows the output from the stylesheet with a lookup table. Figure 7-3. Document generated with a lookup table