Subject: RE: [xsl] line numbering From: "Andrew Welch" <ajwelch@xxxxxxxxxxxxxxx> Date: Thu, 5 Aug 2004 15:17:05 +0100 |
> Hi there, > > I have some poems marked up something like: > > <body> > <div type="poem"> > <lg type="stanza"> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > </lg> > <lg type="stanza"> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > </lg> > <p>This is something not counted as a line</p> > <lg type="stanza"> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > <l>This is a line of verse</l> > </lg> > </div> > <!-- and multiple poem div's like this here... --> > </body> > > What I want to end up with is for each line to be > given an @id in the html output like: > <span id="poem3line10">This is a line of verse <span > class="number">10</span></span> > > <xsl:template match="l"> > <xsl:variable name="linenumber" > select="count(preceding-sibling::l)+1"/> > <span class="line" > id="line{$linenumber}"><xsl:apply-templates /></span> </xsl:template> > > But now I need to account for two factors: > a) that the linenumbering needs to take account of > the existence of the line-groups (lg) and that it > should only count back within it's own <div> ancestor. > b) that I want to number the lines every 5 lines. > > Is position() a better way to do this than counting the > preceding-sibilings? If you have a large input xml you may find counting preceding siblings to be expensive, and that its better to do the numbering in a variable in an initial pass of the xml. For example using this stylesheet: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> <xsl:output indent="yes"/> <xsl:key name="lines" match="line" use="@id"/> <xsl:variable name="lines-rtf"> <xsl:for-each select="/body/div"> <poem number="{position()}"> <xsl:for-each select="lg/l"> <line id="{generate-id()}" number="{position()}"/> </xsl:for-each> </poem> </xsl:for-each> </xsl:variable> <xsl:variable name="lines" select="exsl:node-set($lines-rtf)"/> <xsl:template match="/"> <div> <xsl:apply-templates select="/body/div/lg/l"/> </div> </xsl:template> <xsl:template match="l"> <xsl:variable name="genId" select="generate-id()"/> <span> <xsl:attribute name="id"> <xsl:for-each select="$lines"> <xsl:for-each select="key('lines',$genId)"> <xsl:value-of select="concat('poem',parent::poem/@number,'line',@number)"/> </xsl:for-each> </xsl:for-each> </xsl:attribute> <xsl:value-of select="."/> <xsl:if test="position() mod 5 = 1"> <span class="number"> <xsl:for-each select="$lines"> <xsl:value-of select="key('lines',$genId)/@number"/> </xsl:for-each> </span> </xsl:if> </span> </xsl:template> </xsl:stylesheet> With your example xml gives this result: <div> <span id="poem1line1">This is a line of verse<span class="number">1</span> </span> <span id="poem1line2">This is a line of verse</span> <span id="poem1line3">This is a line of verse</span> <span id="poem1line4">This is a line of verse</span> <span id="poem1line5">This is a line of verse</span> <span id="poem1line6">This is a line of verse<span class="number">6</span> </span> <span id="poem1line7">This is a line of verse</span> <span id="poem1line8">This is a line of verse</span> <span id="poem1line9">This is a line of verse</span> <span id="poem1line10">This is a line of verse</span> <span id="poem1line11">This is a line of verse<span class="number">11</span> </span> <span id="poem1line12">This is a line of verse</span> </div> (I'm not sure if the line numbering 'every five lines' is correct, I would guess you would want 1,5,10,15 and so on, so a bit more logic is required there) In the stylesheet all the numbering is done using the position() function as the nested for-each's iterate over xml. The variable is then queried using a key to maximise performance when accessing the variable. This minimal stylesheet should be O(2n) complexity, counting preceding-siblings would be slightly worse in this case. cheers andrew
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] GUI to Generate Basic XSL, Pieter Reint Siegers | Thread | [xsl] Position() with absolute path, Jeff Cann |
Re: [xsl] line numbering, Mukul Gandhi | Date | [xsl] Position() with absolute path, Jeff Cann |
Month |