Subject: Re: <xsl:number> starting at a preceding-sibling
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Mon, 19 Jan 2009 16:22:17 -0800
|
Thank you very much for the response Dr. Kay,
Unfortunately as I expected level="single" and level="any" to work the
same way in regards to from I made my example document less robust
than it probably should have been. With level="any" the revised xml
source:
<root>
<section>
<level1></level1>
<level1></level1>
<level2></level2>
<level3></level3>
<level2></level2>
<level1></level1>
<level2></level2>
<level3></level3>
</section>
<section>
<level1></level1>
</section>
</root>
would come out:
<root>
<section>
<level1>1</level1>
<level1>2</level1>
<level2>a</level2>
<level3>i</level3>
<level2>b</level2>
<level1>3</level1>
<level2>a</level2>
<level3>i</level3>
</section>
<secton>
<level1>4</level1>
</secton>
</root>
When the second section should start renumbering itself yet again to 1
not 4. Once again my apologies for an inadequate test case.
Spencer
On Mon, Jan 19, 2009 at 4:04 PM, Michael Kay <mike@xxxxxxxxxxxx> wrote:
> Try this:
>
> <xsl:template match="level1">
> <xsl:copy>
> <xsl:number level="any" from="root" format="1"/>
> </xsl:copy>
> </xsl:template>
>
> <xsl:template match="level2">
> <xsl:copy>
> <xsl:number level="any" from="level1" format="a"/>
> </xsl:copy>
> </xsl:template>
>
> <xsl:template match="level3">
> <xsl:copy>
> <xsl:number level="any" from="level2" format="i"/>
> </xsl:copy>
> </xsl:template>
>
> The surprise here (and it took me a while to grasp it) is that level="any"
> is needed even though you're counting siblings. This is because the "from"
> pattern doesn't work the way you want it to with level="single".
>
> Michael Kay
> http://www.saxonica.com/
>
>> -----Original Message-----
>> From: Spencer Tickner [mailto:spencertickner@xxxxxxxxx]
>> Sent: 19 January 2009 23:04
>> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>> Subject: <xsl:number> starting at a preceding-sibling
>>
>> 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(follow
>> ing-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
|