Chapter 14 - Keys and Cross-Referencing | |
XSLT For Dummies | |
by Richard Wagner | |
Hungry Minds 2002 |
The preceding example illustrates how you can use keys to link different XML structures, but it did so within a single XML document. In the real world, you often want to use keys that combine data from various XML files. You can do this by using the document() built-in function. This function allows you to include node sets from external files. As an example, I separate the state- related elements from the customer elements, giving me two source files, Listing 14-1 and Listing 14-2. Listing 14-1: key_state.xml <?xml version="1.0"?> <!-- key_state.xml --> <states region="New England"> <state id="01">Maine</state> <state id="02">New Hampshire</state> <state id="03">Vermont</state> <state id="04">Massachusetts</state> <state id="05">Connecticut</state> <state id="06">Rhode Island</state> </states> Listing 14-2: key_customers.xml <?xml version="1.0"?> <!-- key_customers.xml --> <customers> <customer id="C3020" stateid="04">Bridget McFarland</customer> <customer id="C3021" stateid="04">Cheri Burrer</customer> <customer id="C3022" stateid="02">Greg Stephenson</customer> <customer id="C3023" stateid="05">Mark Horine</customer> <customer id="C3024" stateid="01">Don Shafer</customer> <customer id="C3025" stateid="04">Leo Minster</customer> </customers> In the result document, suppose Id like to provide a simple listing of the customer and his or her state as I do in the initial example of the chapter. To do so, in my XSLT stylesheet, I can define a StatesLookup variable to be the returning node set of the document('key_state.xml') function: <xsl:variable name="StatesLookup" select="document('key_state.xml')"/> Therefore, when I plug in the StatesLookup variable in my stylesheet, it references the states element and its contents. A key is defined for the state elements from the outside file: <xsl:key name="StateKey" match="state" use="@id"/> To perform the key lookup on these elements from another document, I need to set up an xsl:for-each loop to iterate through each of the state elements, calling key() each time to do the lookup. Because the lookup value for the key is the stateid attribute for the customer element, I package it all in a customer template rule: <xsl:template match="customer"> <xsl:variable name="custstate" select="@stateid"/> <xsl:variable name="custname" select="."/> <xsl:for-each select="$StatesLookup"> <xsl:value-of select="$custname"/> lives in <xsl:value- of select="key('StateKey', $custstate)"/> <xsl:text>. </xsl:text> </xsl:for-each> </xsl:template> The entire XSLT stylesheet is as follows : <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <!-- Assign contents of key_state.xml to var --> <xsl:variable name="StatesLookup" select="document('key_state.xml')"/> <!-- Define key --> <xsl:key name="StateKey" match="state" use="@id"/> <!-- Plug in key value --> <xsl:template match="customer"> <xsl:variable name="custstate" select="@stateid"/> <xsl:variable name="custname" select="."/> <xsl:for-each select="$StatesLookup"> <xsl:value-of select="$custname"/> lives in <xsl:value- of select="key('StateKey', $custstate)"/> <xsl:text>. </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet> When the stylesheet is applied to the key customers.xml file (refer to Listing 14-2), the result from the transformation is shown here: Bridget McFarland lives in Massachusetts. Cheri Burrer lives in Massachusetts. Greg Stephenson lives in New Hampshire. Mark Horine lives in Connecticut. Don Shafer lives in Maine. Leo Minster lives in Massachusetts.
|