xsl-list
[Top] [All Lists]

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

2009-01-20 03:29:38
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(_at_)gmail(_dot_)com] 
Sent: 20 January 2009 00:22
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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(_at_)saxonica(_dot_)com> 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(_at_)gmail(_dot_)com]
Sent: 19 January 2009 23:04
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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


--~------------------------------------------------------------------
XSL-List info and archive:  
http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--