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

Subject: RE: [xsl] <xsl:number> starting at a preceding-sibling
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 20 Jan 2009 08:29:05 -0000
You can handle that by extending the from condition, for example

from="level1|section".

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Spencer Tickner [mailto:spencertickner@xxxxxxxxx] 
> Sent: 20 January 2009 00:22
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] <xsl:number> starting at a preceding-sibling
> 
> 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