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

Subject: Re: [xsl] <xsl:number> starting at a preceding-sibling
From: Spencer Tickner <spencertickner@xxxxxxxxx>
Date: Mon, 19 Jan 2009 19:50:53 -0800
As a follow up I'm having a hard time discerning why "from" should act
differently between a "level" of single and a "level" of any?

On Mon, Jan 19, 2009 at 4:22 PM, Spencer Tickner
<spencertickner@xxxxxxxxx> wrote:
> 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] <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

Current Thread