[xsl] <xsl:number> starting at a preceding-sibling

Subject: [xsl] <xsl:number> starting at a preceding-sibling
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Mon, 19 Jan 2009 15:03:35 -0800
Hi List and thanks in advance for the help.

I'm attempting to number some flat xml using xslt 2.0 and am
struggling a bit. Given:

<root>
	<level1></level1>
	<level1></level1>
	<level2></level2>
	<level3></level3>
	<level2></level2>
	<level1></level1>
	<level2></level2>
	<level3></level3>
</root>

I need to number each level based on it's preceding-sibling so it
would look like:

<root>
	<level1>1</level1>
	<level1>2</level1>
	<level2>a</level2>
	<level3>i</level3>
	<level2>b</level2>
	<level1>3</level1>
	<level2>a</level2>
	<level3>i</level3>
</root>

Counting <level1> is easy with <xsl:number> but the template for
<level2> and <level3>. Stylesheet is below, template for level3 is
ommited as it will hinge on solving the template for level2 (I know
all the variables are pretty ugly):

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

<xsl:template match="/">
	<xsl:apply-templates/>
</xsl:template>


<xsl:template match="*">
	<xsl:copy>
		<xsl:copy-of select="@*"/>
		<xsl:apply-templates/>
	</xsl:copy>
</xsl:template>

<xsl:template match="level1">
<xsl:copy>
<xsl:number count="level1" level="single" format="1"/>
</xsl:copy>
</xsl:template>

<xsl:template match="level2">
	<xsl:variable name="cousins" select="preceding-sibling::*"/>
	<xsl:variable name="num">
		<xsl:value-of
select="count($cousins[last()]/preceding-sibling::*[not(following-sibling::level1)][name()
= 'level2'])"/>
	</xsl:variable>
	<xsl:variable name="renum">
		<xsl:choose>
		<xsl:when test="$cousins[last()]/name() = name(.)"><xsl:value-of
select="number($num) + 2"/></xsl:when>
		<xsl:otherwise><xsl:value-of select="number($num) + 1"/></xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
	<xsl:copy>
	<xsl:number value="$renum" format="a"/>	
	</xsl:copy>
</xsl:template>

</xsl:stylesheet>


Any advice would be appreciated.

Thanks,

Spencer

Current Thread