Subject: [xsl] Re: Counting number of characters of sibling text node From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Wed, 22 May 2002 07:01:03 -0700 (PDT) |
And here's a functional solution. Just use the scanl() function from FXSL, passing to it a list of text nodes, an initial value 0 and a function, which adds to the current result the string-length() of the current argument. This will give you all partial sums of string-lengths. If you want the sum just for one text node, you'll use almost the same solution, but the FXSL function should be foldl(), not scanl(). stylesheet: ---------- <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:addLength="f:addLength" exclude-result-prefixes="addLength" > <xsl:import href="scanl.xsl"/> <addLength:addLength/> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:variable name="vAddLength" select="document('')/*/addLength:*[1]"/> <xsl:call-template name="scanl"> <xsl:with-param name="pFun" select="$vAddLength"/> <xsl:with-param name="pQ0" select="0"/> <xsl:with-param name="pList" select="/t/text()"/> </xsl:call-template> </xsl:template> <xsl:template match="addLength:*"> <xsl:param name="pArg1"/> <xsl:param name="pArg2" select="/.."/> <xsl:value-of select="$pArg1 + string-length($pArg2)"/> </xsl:template> </xsl:stylesheet> source xml: ---------- <t><br/>a<br/>ab<br/>abc<br/>abcd</t> Result: ------ <el>0</el> <el>1</el> <el>3</el> <el>6</el> <el>10</el> Cheers, Dimitre Novatchev. --- Dimitre Novatchev <dnovatchev@xxxxxxxxx> wrote: > > What I want to do is to count the number os characters in a text > > node and all previous text nodes children of the current text > node's > > parent. > > > > parent > > | > > ---------------------------- > > | | | | > > text1 <br/> text2 <br/> > > > > > > When having text1 has the current node my template would return > the > > number of characters of text1 but when having text2 has the current > > > node my template would return the sum of number of characters of > > text1 with number of characters of text2. > > > > I've tried using the following template: > > > > <xsl:template match="text()" mode="getStrLen"> > > <xsl:variable name="pastTxtLen"><xsl:apply-templates > > select="preceding-sibling::text()[1]" > > mode="getStrLen"/></xsl:variable> > > <xsl:value-of select="string-length($pastTxtLen) + string-length > > (.)" /> > > </xsl:template> > > > > I get it's result by doing: > > <xsl:variable name="pastTxtLen"><xsl:apply-templates select="." > > mode="getStrLen"/></xsl:variable> > > > > Doing it this way I get the rong result. > > For the example above, when I have text1 has the current node it > > works fine(the number of characters of text1 only is returned) but > > when I have text2 has the current node a rong result. > > > > Any suggestions? > > You're almost there, just two things: > > 1. Change > > > <xsl:value-of select="string-length($pastTxtLen) + string-length > > (.)" /> > > to > > <xsl:value-of select="$pastTxtLen + string-length(.)" /> > > > 2. In case there are no preceding siblings that are text nodes, the > value of $pastTxtLen will be the empty nodeset, which is not a > number. > As a result you'll get NaN adding to it anything. Therefore, you need > to process this special case in an appropriate way. > > Here's one solution: > > stylesheet: > ---------- > <xsl:stylesheet version="1.0" > xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> > <xsl:output omit-xml-declaration="yes"/> > > <xsl:strip-space elements="*"/> > > <xsl:template match="/"> > > <xsl:for-each select="/t/text()"> > <xsl:apply-templates select="." mode="getStrLen"/> > <xsl:text> </xsl:text> > </xsl:for-each> > </xsl:template> > <xsl:template match="text()" mode="getStrLen"> > <xsl:variable name="vPrecText" > select="preceding-sibling::text()[1]"/> > <xsl:variable name="pastTxtLen"> > <xsl:choose> > <xsl:when test="$vPrecText"> > <xsl:apply-templates mode="getStrLen" > select="$vPrecText[1]" /> > </xsl:when> > <xsl:otherwise>0</xsl:otherwise> > </xsl:choose> > </xsl:variable> > <xsl:value-of select="$pastTxtLen + string-length(.)" /> > </xsl:template> > </xsl:stylesheet> > > source xml: > ---------- > <t><br/>a<br/>ab<br/>abc<br/>abcd</t> > > Result: > ------ > 1 > 3 > 6 > 10 > > > Cheers, > Dimitre Novatchev. > > > > > __________________________________________________ > Do You Yahoo!? > LAUNCH - Your Yahoo! Music Experience > http://launch.yahoo.com > __________________________________________________ Do You Yahoo!? LAUNCH - Your Yahoo! Music Experience http://launch.yahoo.com XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Re: Counting number of charac, Dimitre Novatchev | Thread | AW: [xsl] XML Reorganisation, Fries, Markus, fiscu |
Re: [xsl] Regarding XSL performance, Anand Ganapathy | Date | RE: [xsl] one key or a whole bunch?, Michael Kay |
Month |