|
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 |