Determining the Context Size

MSXML 5.0 SDK

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

Determining the Context Size

Many XPath expressions locate just a single node in the source tree. For example, referring to the sample XML document introduced earlier in this topic, this XPath expression:

today

locates just one element node.

However, in many other cases the XPath expression locates more than one node or rather, an indeterminate number of nodes, ranging from 0 on up—that is, a node-set. For example:

forecast

When applied to the sample document, it locates not just a single node but a node-set, and the size of that node-set—the number of nodes in it, or two in this case—can be critical in determining what your style sheet needs to do at a given point.

The context size is always accessible as the value of the XPath last() and count() functions, each returning an integer. Use last() when you are already working with the node-set in question. Use count() when you need to pass it to another node-set. This can be used for calculating the average of all temperatures in your sample weather-related XML document, when used in concert with the sum() function.

The last() and count() functions are useful in laying out tables whose number of columns, fare fixed but whose number of rows vary depending on the number of occurrences of some element in the source tree.

For more information about last() and count(), see Processing Node-Sets by Using Node-Set Functions. For more information about sum(), see Using Numeric Functions to Perform Math Operations in XPath.

Example

XML File (weather.xml)

Change the href attribute in weather.xml (shown in Sample XML Data File for XPath Context and Navigation) to reference weatherconsize.xsl.

XSLT File (weatherconsize.xsl)

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- suppress text nodes not covered in subsequent template rule -->
<xsl:template match="text()"/>

<xsl:template match="/">
   Average temperature (for
   <xsl:value-of select="count(.//temperature)"/> days) : 
   <xsl:value-of 
     select="sum(.//temperature) div count(.//temperature)"/> degrees
</xsl:template>

</xsl:stylesheet>

Formatted Output

Average temperature (for 3 days) : 76.33333333333333 degrees

Processor Output

<?xml version="1.0" encoding="UTF-16"?>
Average temperature (for
3 days) : 
76.33333333333333 degrees