Using level="multiple" for Numbering

MSXML 5.0 SDK

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

Using level="multiple" for Numbering

In this topic, we add the level, format, and count attributes to the <xsl:number> element of our existing style sheet, cardgame_orig.xsl. The original file is in Inserting Automatic Numbering Using position(). The following snippet shows the new attributes and their values in bold.

<xsl:template match="player">
    <h2>
        Player 
        <xsl:number 
            level="multiple" 
            format="1.1" 
            count="hand | player"/>:
        <xsl:value-of select="@name"/>
    </h2>
    <xsl:apply-templates/>
</xsl:template>

The level attribute with the value "multiple" indicates that this will be a hierarchical number. The format attribute indicates that the hierarchy will be represented as a string of period-delimited integers (such as 1.1 or 1.2, and so on). The count attribute includes a list of elements along the ancestor-or-self:: axis, separated by a pipe (|).These elements are to be used in determining the number to be displayed.

Output from this version of the style sheet now appears as follows:

Note that the player numbers now include the hand number, in the following format.

handnumber.playernumber

The next step is to add the <xsl:template match="card"> template rule to process the individual cards dealt in each hand. Again, we'll use <xsl:number> to number them according to their sequence within each hand dealt, and within each <player> element to which the <card> elements belong. This time, however, we'll change the formatting card numbers within each hand/player hierarchy, so that each card will be represented with two digits instead of one. For example, the following card number would represent the fourth card dealt to player #1 in hand #2.

2.1.04

We'll also add some code to generate a <table> element and table headings for each group of cards. Our two template rules from cardgame_orig.xsl now look like this:

<xsl:template match="player">
    <h2>
        Player 
        <xsl:number 
            level="multiple" 
            format="1.1" 
            count="hand | player"/>:
        <xsl:value-of select="@name"/>
    </h2>
    <table width="75%">
        <tr>
            <th>Card #</th>
            <th>Rank/Suit</th>
            <th>Replaces</th>
        </tr>
        <xsl:apply-templates/>
    </table>
</xsl:template>

<xsl:template match="card">
    <tr>
        <td align="center" width="30%">
            <xsl:number
                level="multiple" 
                format="1.1.01" 
                count="hand | player | card"/>
        </td>
        <td width="40%">
            <xsl:value-of select="rank"/>
            <xsl:text> of </xsl:text>
            <xsl:value-of select="suit"/>
        </td>
        <td>
            <xsl:choose>
                <xsl:when test="@replace">
                    <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/rank"/>
                    of <xsl:value-of select="preceding::card[@dealtID=current()/@replace]/suit"/>
                </xsl:when>
                <xsl:otherwise>--</xsl:otherwise>
            </xsl:choose>
        </td>
    </tr>
</xsl:template>
Note   The values inserted into the last column (headed "Replaces") use a complex pair of XPath expressions. For each <card> element, these expressions obtain the rank and suit of the preceding <card> element whose dealtID attribute matches the replace attribute of the current <card> element. If there is no such preceding <card>, this table cell contains a pair of hyphens (--).

A portion of the results when viewed in Internet Explorer looks like this: