Subject: Re: [xsl] counting element characters From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Sun, 10 Aug 2008 16:10:35 -0700 |
> <xsl:variable name="c"> > <xsl:for-each select="descendant::p"> > <xsl:value-of select="string-length(.)"/> > </xsl:for-each> > </xsl:variable> > <xsl:value-of select="sum($c/text())"/> This is defining a variable $c of type document-node() and the sequence constructor that produces its value produces a sequence of text() nodes. In any xml tree there cannot be two adjacent text nodes -- they are merged on creating the tree. Therefore, $c is a document-node() that has a single text node child. $c/text() is the total output produced by the <xsl:value-of> instruction. The expression: sum($c/text()) is producing the sum of a sequence of one item and the result is simply this same item -- the value of the $c variable (the concatenation of all results of <xsl:value-of>) In the case of the given source xml document: > <doc> > <a> > <p>some text to be counted</p> <!-- 23 chars there --> > <x>other text</x> > <p>some more text to be counted</p> <!-- 28 chars --> > </a> > </doc> this result is: 2328 One correct way to specify the desired processing is the following: <xsl:template match="a"> <xsl:variable name="c" as="text()*"> <xsl:for-each select="descendant::p"> <xsl:value-of select="string-length(.)"/> </xsl:for-each> </xsl:variable> <xsl:value-of select="sum($c)"/> </xsl:template> and it produces the following result, when the template is applied on the "a" element of the above document: 51. Cheers, Dimitre Novatchev On Sun, Aug 10, 2008 at 3:17 PM, tom s <tshmit@xxxxxxxxx> wrote: > I'm almost as embarrassed by this question as I am baffled by it....I'd like to sum the number of PCDATA characters contained in specified elements. For example: > > <doc> > <a> > <p>some text to be counted</p> <!-- 23 chars there --> > <x>other text</x> > <p>some more text to be counted</p> <!-- 28 chars --> > </a> > </doc> > > I'd like to calculate the sum of characters in the <p> tags; here 51. > > I thought I would use something like: > <xsl:template match="a"> > <xsl:variable name="c"> > <xsl:for-each select="descendant::p"> > <xsl:value-of select="string-length(.)"/> > </xsl:for-each> > </xsl:variable> > <xsl:value-of select="sum($c/text())"/> > </xsl:template> > > This seems to work in the xmlspy processor, but saxon generates values like 3.0010118811741284E51, which is substantially more than the number of atoms in the universe, I think. I assume it is some sort of type problem... > > Also, if it happens that <a> contains no <p> elements, saxon complains that it can't convert an empty string to a double. I tried conditioning the evaluation of the sum() on <xsl:when test="count($c/text()) > 0">, to avail. > > Any help is greatly appreciated!! > > -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- Never fight an inanimate object ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] counting element characters, tom s | Thread | Re: [xsl] counting element characte, Florent Georges |
[xsl] counting element characters, tom s | Date | Re: [xsl] Apache FOP 0.94 and curre, Kamal Bhatt |
Month |