Reputation: 21
I am confronted to what I thought it was a simple problem but I am stuck. Here is an xml data
<?xml version="1.0" encoding="UTF-8"?>
<report endDate="2013/02/01 15:10:14" environment="Q000" startDate="2013/01/25 15:10:14">
<distrib appCode="LI" busLine="IL" context="" id="2013-01-25-15.10.11.785293" network="FBB" subNetwork="Z">
<deliv id="2013-01-25-15.10.11.785295" mode="1" role="">
<comm id="2013-01-25-15.10.11.785297" role="">
<group id="001">
<doc id="950955269" nbPages="1" templateId="LVMED1" />
</group>
<group id="002">
<doc id="950955270" nbPages="6" templateId="BALVANW_FA" />
</group>
<group id="003">
<doc id="950955271" nbPages="" templateId="LVMED23" />
</group>
</comm>
</deliv>
</distrib>
<distrib appCode="LI" busLine="IL" context="" id="2013-01-25-15.18.29.871466" network="FBB" subNetwork="Z">
<deliv id="2013-01-25-15.18.29.871468" mode="1" role="">
<comm id="2013-01-25-15.18.29.871469" role="">
<group id="001">
<doc id="950955331" nbPages="2" templateId="LVMED10" />
</group>
</comm>
</deliv>
</distrib>
</report>
I would like to sum the content of attributes nbPages in elements 'doc'
Here is the xslt I use:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text" />
<xsl:template match="report">
<xsl:value-of select="count(//doc)"/>
<xsl:value-of select="sum(//doc[@nbPages])"/>
</xsl:template>
</xsl:stylesheet>
The count works well, but the sum does not.
[Saxon-PE 9.3.0.5] Cannot convert string {} to a double
I have tried using the following alternatives without success:
<xsl:value-of select="sum(number(//doc[@nbPages]))"/>
<xsl:value-of select="sum(//doc[number(@nbPages)])"/>
Any help would be very appreciated on this.
Upvotes: 2
Views: 4717
Reputation: 18064
Your XPATH is wrong for sum function.
Since
//doc[@nbPages]
: This XPath returns nodes, not the values of nbPages
attribute.
Do it this way:-
//doc[not(@nbPages) or @nbPages!='']/@nbPages
: This XPath checks that the nbPages
attributes exists and is not empty.
sum(//doc[not(@nbPages) or @nbPages!='']/@nbPages)
<xsl:value-of select="sum(//doc[not(@nbPages) or @nbPages!='']/@nbPages)"/>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output method="text"/>
<xsl:template match="report">
<xsl:value-of select="count(//doc)"/>
<xsl:value-of select="sum(//doc[not(@nbPages) or @nbPages!='']/@nbPages)"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2
Reputation: 243459
Use:
sum(//doc/@nbPages[number(.) = number(.)])
Here is a complete transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:value-of select="sum(//doc/@nbPages[number(.) = number(.)])"/>
</xsl:template>
</xsl:stylesheet>
producing the correct result:
9
Upvotes: 4
Reputation: 66
Use xpath expression like this:
<xsl:value-of select="sum(//doc/@nbPages)"/>
Same issue is here: xsl summation
Upvotes: 0