Subject: Re: [xsl] Dealing without global counters From: "M. David Peterson" <m.david@xxxxxxxxxx> Date: Wed, 12 Nov 2003 01:57:10 -0700 |
It occured to me that a slightly more efficient way to get the textual value of of a number would be similar to what Dimitre mentioned earlier... Adding this to the top of your stylesheet <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:textValue="my::textValue" exclude-result-prefixes="textValue" > <textValue:textValueofNumber> <number value="1">First</number> <number value="2">Second</number> <number value="3">Third</number> <number value="4">Fourth</number> <number value="5">Fifth</number> <number value="6">Sixth</number> <number value="7">Seventh</number> </textValue:textValueofNumber> <xsl:variable name="textValueofNumber" select="document('')/*/textValue:*"/> and then using this for your "textValueofNumber" template... <xsl:template name="textValueofNumber"> <xsl:param name="position"/> <xsl:value-of select="$textValueofNumber/*[@value=$position]"/> </xsl:template> Makes the whole process a lot less expensive, much more efficient, and WAY easier to maintain! Best regards! M. ----- Original Message ----- From: "M. David Peterson" <m.david@xxxxxxxxxx> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Sent: Wednesday, November 12, 2003 12:59 AM Subject: Re: [xsl] Dealing without global counters > A solution that might add a bit of efficiency as well as give you the > ability to use the textual representation of the numbers (the way you had it > in your desired output) is as follows... > > the following template outputs: > > db[1]=new dbRecord(Chapter 1) > db[2]=new dbRecord( First Paragraph testPara_one ) > db[3]=new dbRecord( Second Paragraph testPara_two ) > db[4]=new dbRecord( Third Paragraph testPara_three ) > db[5]=new dbRecord( Fourth Paragraph testPara_four ) > db[6]=new dbRecord( First Image testImage_one ) > db[7]=new dbRecord( Second Image testImage_two ) > db[8]=new dbRecord( First Table testTable ) > > when using the input: > > <chapters> > <chapter> > <para>testPara_one > </para> > <para>testPara_two > </para> > <image>testImage_one > </image> > <para>testPara_three > </para> > <image>testImage_two > </image> > <table>testTable > </table> > <para>testPara_four > </para> > </chapter> > </chapters> > > The template is as follows... > > <xsl:template match="/"> > <xsl:apply-templates/> > </xsl:template> > > <xsl:template match="chapters/chapter"> > > db[1]=new dbRecord(Chapter <xsl:number/>)<br/> > > <xsl:for-each select="para"> > <xsl:variable name="count"><xsl:number/></xsl:variable> > db[<xsl:value-of select="$count + 1"/>]=new dbRecord( > <xsl:call-template name="textValueofNumber"> > <xsl:with-param name="position"> > <xsl:number/> > </xsl:with-param> > </xsl:call-template> > Paragraph <xsl:value-of select="."/>)<br/> > > </xsl:for-each> > > <xsl:for-each select="image"> > <xsl:variable name="count"><xsl:number/></xsl:variable> > <xsl:variable name="paraCount"><xsl:value-of > select="count(../child::para)"/></xsl:variable> > db[<xsl:value-of select="$count + $paraCount + 1"/>]=new dbRecord( > <xsl:call-template name="textValueofNumber"> > <xsl:with-param name="position"> > <xsl:number/> > </xsl:with-param> > </xsl:call-template> >  Image <xsl:value-of select="."/>)<br/> > </xsl:for-each> > > > <xsl:for-each select="table"> > <xsl:variable name="count"><xsl:number/></xsl:variable> > <xsl:variable name="childCount"><xsl:value-of > select="count(../child::*)"/></xsl:variable> > db[<xsl:value-of select="$count + $childCount"/>]=new dbRecord( > <xsl:call-template name="textValueofNumber"> > <xsl:with-param name="position"> > <xsl:number/> > </xsl:with-param> > </xsl:call-template> >  Table <xsl:value-of select="."/>)<br/> > </xsl:for-each> > > </xsl:template> > > <xsl:template name="textValueofNumber"> > > <xsl:param name="position"/> > > <xsl:choose> > <xsl:when test="$position = '1'"> > First > </xsl:when> > <xsl:when test="$position = '2'"> > Second > </xsl:when> > <xsl:when test="$position = '3'"> > Third > </xsl:when> > <xsl:when test="$position = '4'"> > Fourth > </xsl:when> > > ... etc... through the reach of numbers you think you will need. > > </xsl:choose> > > </xsl:template> > > Best of luck! > > M. > > ----- Original Message ----- > From: "Jeni Tennison" <jeni@xxxxxxxxxxxxxxxx> > To: "Robert Ogden" <Robert.Ogden@xxxxxxxx> > Cc: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> > Sent: Wednesday, November 12, 2003 12:11 AM > Subject: Re: [xsl] Dealing without global counters > > > > Hi Robert, > > > > > Output (this output is a javascript array for an expandable TOC) > > > db[1]=new dbRecord(chapter stuff) > > > db[2]=new dbRecord(first para stuff) > > > db[3]=new dbRecord(second para stuff) > > > db[4]=new dbRecord(third para stuff) > > > db[5]=new dbRecord(fourth para stuff) > > > db[6]=new dbRecord(first image stuff) > > > db[7]=new dbRecord(second image stuff) > > > db[8]=new dbRecord(first table stuff) > > > > > > What I want to do is output a chapter, all text in a chapter, then > > > all images for a chapter, and lastly all tables for a chapter. This > > > is done repetitively for each chapter. > > > > A simple-minded solution might be the following. You can calculate the > > number for a chapter using <xsl:number> with level="any" (counting > > elements at any level in the document) and with the count attribute > > matching those elements you're interested in counting: chapter, paras, > > tables and images. > > > > Once you've output the line for the chapter, you can go on to process > > its <para> children, then its <image> children, then its <table> > > children. When processing the <para> elements, you want to start > > counting from the number for the chapter; when processing the <image> > > elements, you want to start counting from the number for the chapter > > plus the number of <para> children the chapter has; similarly, when > > processing the <table> children, you want to start counting from the > > number for the chapter plus the number of <para> or <image> children > > the chapter has: > > > > <xsl:template match="chapter"> > > <xsl:variable name="number"> > > <xsl:number level="any" count="chapter | para | table | image" /> > > </xsl:variable> > > > > <xsl:value-of > > select="concat('db[', $number, ']=new dbRecord(chapter stuff)
')" > /> > > > > <xsl:apply-templates select="para"> > > <xsl:with-param name="start" select="$number" /> > > </xsl:apply-templates> > > <xsl:apply-templates select="image"> > > <xsl:with-param name="start" select="$number + count(para)" /> > > </xsl:apply-templates> > > <xsl:apply-templates select="table"> > > <xsl:with-param name="start" select="$number + count(para | image)" /> > > </xsl:apply-templates> > > </xsl:template> > > > > When it comes to processing the <para>, <image> and <table> elements, > > the $start parameter gives you the starting number. The number for the > > <para>, <image> or <table> is this starting number plus the number for > > the particular <para>, <image> or <table>, which you can again get via > > the <xsl:number> instruction: > > > > <xsl:template match="para | image | table"> > > <xsl:param name="start" select="0" /> > > <xsl:variable name="number"><xsl:number /></xsl:variable> > > <xsl:value-of > > select="concat('db[', $start + $number, > > ']=new dbRecord(', name(), ' stuff)
')" /> > > </xsl:template> > > > > > > This approach isn't very efficient -- numbering with <xsl:number> > > seldom is, especially with level="any" -- but that might not be a > > problem for you. > > > > In XSLT 2.0, you can create a sequence that contains the elements that > > you want to process in the correct order, and then iterate over that > > sequence, using the position() function to provide the relevant > > numbers. The code would look something like: > > > > <xsl:variable name="elements" as="element()*"> > > <xsl:for-each select="chapter"> > > <xsl:sequence select="(., para, image, table)" /> > > </xsl:for-each> > > </xsl:variable> > > <xsl:for-each select="$elements"> > > <xsl:value-of > > select="concat('db[', xs:string(position()), > > ']=new dbRecord(', name(), ' stuff)
')" /> > > </xsl:for-each> > > > > Cheers, > > > > Jeni > > > > --- > > Jeni Tennison > > http://www.jenitennison.com/ > > > > > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > > > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Dealing without global co, M. David Peterson | Thread | RE: [xsl] Dealing without global co, Michael Kay |
[xsl] Getting the value of ancestor, asim | Date | [xsl] Outline a header, Barry van Weldam |
Month |