Larry
Larry

Reputation: 11919

Specify XPath to count the value of a set of child-nodes?

Is it possible to specify an XPath query such that it can count the number at the text-value of a set of children:

This is best explained with an example, for instance:

    <badge_counts>
        <gold>2</gold>
        <silver>15</silver>
        <bronze>32</bronze>
    </badge_counts>

Thus, is it possible to specify an Xpath, to get total_badges = 49. (from: 2+15+32)

Upvotes: 2

Views: 1207

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243449

Use:

sum(/*/*)

This produces the sum, of the string-values converted to number, of all elements in the XML document that are children of the top element of the document.

As a rule: Whenever possible try to avoid using the // pseudo-operator, because this may lead to unwanted inefficient evaluation -- many XPath engines in this case perform complete traversal of the whole tree rooted in the context node.

XSLT - based verification:

This transformation:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="/">
     <xsl:value-of select="sum(/*/*)"/>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<badge_counts>
    <gold>2</gold>
    <silver>15</silver>
    <bronze>32</bronze>
</badge_counts>

evaluates the XPath expression and outputs the result:

49

Upvotes: 2

MattH
MattH

Reputation: 38247

How about:

sum(//badge_counts/*/text())

Python example:

>>> from lxml import etree
>>> doc = etree.XML("""<badge_counts><gold>2</gold><silver>15</silver><bronze>32</bronze></badge_counts>""")
>>> doc.xpath('//badge_counts/*/text()')
['2', '15', '32']
>>> doc.xpath('sum(//badge_counts/*/text())')
49.0

Upvotes: 0

Related Questions