Microsoft XML SDK 2.6 - XSLT Developer's Guide

How XSLT Defines the Context for XPath Expressions

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 XPath expressions within the template.

XPath expressions are accepted as attribute values for <xsl:value-of>, <xsl:for-each>, <xsl:apply-templates>, <xsl:if>, <xsl:when>, <xsl:copy-of>, <xsl:param>, <xsl:sort>, <xsl:variable>, <xsl:with-param>, 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.

Select Expressions

The <xsl:value-of>, <xsl:for-each>, <xsl:copy-of>, <xsl:param>, <xsl:sort>, <xsl:variable>, <xsl:with-param>, and <xsl:apply-templates> elements have a select attribute. This expression is evaluated relative to the template's current node. In <xsl:for-each> or <xsl:apply-templates>, the select returns a node-set, and 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.

Because each expression 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. xmconPlacingItemsintoaGridxmconCreatingCommaSepList

Test Boolean Expressions

The conditional elements <xsl:if> and <xsl:when> do not define a new context for queries within themselves because they do not 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[.>=10]">
          <xsl:for-each select="price">
            <xsl:value-of select="formatNumber(.*.10, '$#,##0.00')"/>
          </xsl:for-each>
        </xsl:if>
      </TD>
      <TD STYLE="text-align:right"> <!-- line total -->
        <xsl:value-of select="formatNumber(user:lineTotal(.), '$#,##0.00')"/> 
      </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.

Match Patterns

The <xsl:template> element has a match attribute that accepts a 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!   The above example can be found within the Invoice sample at XSLT Developer's Guide Samples.

For the XSL version of this sample, see XSL Developer's Guide Samples.