Using Variables to Cache XPath Expressions

MSXML 5.0 SDK

Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Using Variables to Cache XPath Expressions

Because XPath expressions can be long, writing them manually can be cumbersome and prone to typographical errors, especially when you plan to use them multiple times. To avoid this problem, you can write an XPath expression once, and cache it in an XSLT variable.

Suppose we want to display the average high temperature for each day listed in the weatherlog.xml file in Initial XSLT Example Using Variables. The following XPath expression will do just that.

format-number(sum(locale/temp/high) div count(locale), '##0.00')

We could then use this expression in an XSLT element directly, as follows:

<xsl:value-of select="format-number(sum(locale/temp/high) div count(locale), '##0.00')">

But if we wanted to use this expression in other parts of the XSLT style sheet, we would have to type this rather complicated expression again. A more efficient way is to cache this expression in an XSLT variable:

<xsl:variable name="average_temp"
      select="format-number(
                   sum(locale/temp/high) div count(locale),
                   '##0.00')"
/>

Then call the expression by referencing the variable:

<xsl:value-of select="$average_temp"/>

The following is a revised XSLT style sheet:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/TR/REC-html40">

<xsl:template match="/">
   <HTML>
      <HEAD>
         <TITLE>Weather Readings</TITLE>
      </HEAD>
      <BODY>
         <xsl:apply-templates/>
      </BODY>
   </HTML>
</xsl:template>

<!-- Override built-in template rule for text nodes. -->
<xsl:template match="text()"/>

<xsl:template match="weather">
   <H1>Weather Readings</H1>
   <xsl:for-each select="day">
      <xsl:variable name="average_temp" select="format-number(
                   sum(locale/temp/high) div count(locale), 
                   '##0.00')"/>
      <H2>As of <xsl:value-of select="@date"/></H2>
      <P>
         Average Temperature: 
         <xsl:value-of select="$average_temp"/>&#176;F
      </P>
      <xsl:for-each select="locale">
         <xsl:variable name="placename">
             <xsl:choose>
                 <xsl:when test="@place='location1'">Midtown</xsl:when>
                 <xsl:when test="@place='location2'">Northeast</xsl:when>
                 <xsl:when test="@place='location3'">Airport</xsl:when>
                 <xsl:otherwise>[Unknown Locale]</xsl:otherwise>
             </xsl:choose>
         </xsl:variable>
         <H3><xsl:value-of select="$placename"/></H3>
      </xsl:for-each>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
Note   The above template includes a reference to an entity, &#176;, which displays in Microsoft Internet Explorer as the degrees symbol, "°".

For more information, see the Finished XSLT Example Using Variables.