At run time, templates in a style sheet are associated with specific source nodes, starting with the document root node that is associated with the root template (match="/"). Within the template, the associated source node is referred to as the current node. The current node defines a context for evaluating XSL Pattern queries within the template.
XSL Patterns are accepted as attribute values for <xsl:value-of>, <xsl:for-each>, <xsl:apply-templates>, <xsl:if>, <xsl:when>, and <xsl:template>. The various attribute names define how the context for the query is determined and whether or not it results in a new context.
The <xsl:value-of>, <xsl:for-each>, and <xsl:apply-templates> elements have a select attribute. This query is evaluated relative to the template's current node, and identifies a set of new nodes. In <xsl:for-each> or <xsl:apply-templates>, each node in this set becomes the current node for further queries within it.
<TABLE BORDER="1"> <xsl:for-each select="invoices/invoice"> <TR> <TD>Invoice #<xsl:value-of select="@id"/></TD> </TR> <xsl:for-each select="items/item"> <TR> <TD><xsl:value-of select="qty"/></TD> <TD><xsl:value-of select="description"/></TD> <TD>$<xsl:value-of select="price"/></TD> </TR> </xsl:for-each> </xsl:for-each> </TABLE>
The first <xsl:for-each> selects a set of "invoice" elements, each of which becomes the context for the "items/item" query. Each "item" in turn becomes the context for the various queries in the <xsl:value-of> elements.
Each node selected by <xsl:apply-templates> is associated with a template and thus becomes the current node for the template.
Since each query defines a new context, a set of nested queries as in the above example produces a set or "path" of context nodes active at one time. Microsoft® Internet Explorer 5 extends XSL Patterns with a context method to refer to these parent contexts. This provides the capability to do simple joins. For examples of using the context function to perform more complex transformations, see Placing a List of Items into a Grid with the context() Method and Creating a Comma-Separated List of Items with the context() Method.
The conditional elements <xsl:if> and <xsl:when> do not define a new context for queries within themselves since they don't actually select new nodes. They just test to make sure they are there.
<TABLE> <xsl:for-each select="items/item"> <TR> <TD><xsl:value-of select="qty"/></TD> <TD><xsl:value-of select="description"/></TD> <TD>$<xsl:value-of select="price"/></TD> <TD> <!-- 10% volume discount --> <xsl:if test="qty[.$ge$10]"> <xsl:for-each select="price"> <xsl:eval>formatNumber(this.nodeTypedValue*.10, "$#,##0.00")</xsl:eval> </xsl:for-each> </xsl:if> </TD> <TD STYLE="text-align:right"> <!-- line total --> <xsl:eval>formatNumber(lineTotal(this), "$#,##0.00")</xsl:eval> </TD> </TR> </xsl:for-each> </TABLE>
In this example you can see that the <xsl:for-each select="price"> query is relative to "item" elements, despite the intervening conditional that tests the "qty" value.
The <xsl:template> element has a match attribute that accepts an XSL Pattern for the purposes of matching templates to specific elements, and thus there is no fixed context for a query in this case. See Authoring Match Patterns.
Try it! See the above example in action at Invoice Sample.