10.2 Calling a Named Template

It's possible to have templates in a stylesheet that don't overtly match any node pattern: you can invoke such templates by name. You assign a template a name by giving it a name attribute. In fact, if a template element does not use a match attribute, it must have a name attribute instead (though it is also permissible for a template to have both match and name attributes).

The call-template instruction element has one required attribute, also called name. The value of the name attribute on a call-template element must match the value of a name attribute on a template element. It's an error to have more than one template with the same name.

When you want to instantiate a named template, ring it up with a call-template element. The advantage of calling named templates is that you can instantiate them on demand rather than only when a given pattern is encountered in a source tree. Also, the context does not change when you call a template by name. Calling a template is similar to calling a function or method in a programming language such as C or Java, but without a return value.

Example 10-6 is a stylesheet that uses the call-template element named call.xsl.

Example 10-6. A stylesheet using call-template
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/>     <xsl:template match="state"> Counties of <xsl:value-of select="@name"/>:  <xsl:call-template name="nl"/>  <xsl:apply-templates select="county"/> </xsl:template>     <xsl:template match="county">  <xsl:text> - </xsl:text>  <xsl:value-of select="."/>  <xsl:call-template name="nl"/> </xsl:template>     <xsl:template name="nl">  <xsl:text>&#10;</xsl:text> </xsl:template> </xsl:stylesheet>

In call.xsl, the template named nl (short for newline) contains a text element that holds a decimal character reference for a single linefeed character (&#10;). The other two templates in the stylesheet call the nl template to insert on demand a single linefeed into the result tree. When applied to ri.xml with:

xalan ri.xml call.xsl

this stylesheet produces:

Counties of Rhode Island:      - Bristol  - Kent  - Newport  - Providence  - Washington

10.2.1 Using the name and match Attributes Together

A template element can have both a name and a match attribute at the same time. This does not happen often, but you might want to do this because you could instantiate a template upon finding a pattern, or you could call the template when desired. I'll give you an example of how this works.

Look at the following similar XML documents in Examples 10-7 and 10-8. These documents show the estimated populations of the respective states, by county, as of July 1, 2001. (This information was garnered from the United States Census Bureau web site, http://www.census.gov.) The first is Example 10-7, delaware.xml.

Example 10-7. Delaware information in XML
<?xml version="1.0"?>     <state name="Delaware">  <description>July 1, 2001 population estimates<description>  <from>U.S. Census Bureau</from>  <url>http://www.census.gov</url>  <county name="Kent">   <population>129066</population>  </county>  <county name="New Castle">   <population>505829</population>  </county>  <county name="Sussex">   <population>161270</population>  </county> </state>

The second document is rhodeisland.xml, shown in Example 10-8.

Example 10-8. Rhode Island information in XML
<?xml version="1.0"?>     <state name="Rhode Island">  <description>July 1, 2001 population estimates<description>  <from>U.S. Census Bureau</from>  <url>http://www.census.gov</url>  <county name="Bristol">   <population>51173</population>  </county>  <county name="Kent">   <population>169224</population>  </county>  <county name="Newport">   <population>85218</population>  </county>  <county name="Providence">   <population>627314</population>  </county>  <county name="Washington">   <population>125991</population>  </county> </state>

The stylesheet in Example 10-9, both.xsl, employs a template that uses both the match and name attributes.

Example 10-9. A stylesheet that uses both match and name attributes on template
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/>     <xsl:template match="state">  <xsl:call-template name="nl"/>  <xsl:text>Counties of </xsl:text>  <xsl:value-of select="@name"/>  <xsl:call-template name="nl"/>  <xsl:text>Description: </xsl:text>  <xsl:value-of select="description"/>  <xsl:call-template name="nl"/>  <xsl:text>Source: </xsl:text>  <xsl:value-of select="from"/>  <xsl:call-template name="nl"/>  <xsl:text>URL: </xsl:text>  <xsl:value-of select="url"/>  <xsl:call-template name="nl"/>  <xsl:apply-templates select="county"/>  <xsl:text>Estimated state population: </xsl:text>  <xsl:value-of select="sum(county/population)"/>  <xsl:call-template name="nl"/> </xsl:template>     <xsl:template match="county">  <xsl:text> - </xsl:text>  <xsl:value-of select="@name"/>  <xsl:text>: </xsl:text>  <xsl:value-of select="population"/>  <xsl:apply-templates select="population"/> </xsl:template>     <xsl:template match="population" name="nl">  <xsl:text>&#10;</xsl:text> </xsl:template> </xsl:stylesheet>

This stylesheet creates a simple text report when used to process documents such as delaware.xml and rhodeisland.xml. As part of the report, it also sums the content of population nodes using the XPath function sum( ).

Like call.xsl, this stylesheet also has a template named nl. The difference is that the template also matches on population nodes. This means that the template is invoked both when a population element is processed (see apply-templates in the template that matches county) and directly by call-template.

The following example processes delaware.xml and rhodeisland.xml with both.xsl using xsltproc, an XSLT processor written in C and based on the C libraries libxslt and libxml2. It runs in a Unix environment such as Linux or as I use it as part of Cygwin on Windows. This processor is available for download from http://xmlsoft.org or as part of the Cygwin distribution available at http://www.cygwin.com.

I'm showing you xsltproc because it allows you to process one or more XML documents against a stylesheet at one time. Here is the command line:

xsltproc both.xsl delaware.xml rhodeisland.xml

The stylesheet comes first, followed by a list of XML documents that you want to process. The outcome of this command is:

Counties of Delaware Description: July 1, 2001 population estimates Source: U.S. Census Bureau URL: http://www.census.gov  - Kent: 129066  - New Castle: 505829  - Sussex: 161270 Estimated state population: 796165     Counties of Rhode Island Description: July 1, 2001 population estimates Source: U.S. Census Bureau URL: http://www.census.gov  - Bristol: 51173  - Kent: 169224  - Newport: 85218  - Providence: 627314  - Washington: 125991 Estimated state population: 1058920

Looking back at the stylesheet, notice where the nl template is invoked directly with multiple instances of call-template. After the stylesheet processes the name and population data of each county by invoking the template that matches county nodes, it then applies templates for population nodes, inserting a linefeed after each node.



Learning XSLT
Learning XSLT
ISBN: 0596003277
EAN: 2147483647
Year: 2003
Pages: 164

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