XSLT recursive sum troubles
When I try to recursive sum an attributes from multiple nodes, it's gluing like string :(
XML-file (second mileage-node include first mileage-node)
<mileage value="15000">
<operation title="Replacing the engine oil" cost="500" />
<sparepart title="Oil filter" cost="250" />
<sparepart title="Motor oil" cost="1050" />
</mileage>
<mileage value="30000">
<repeating mileage="15000" />
<operation title="Replacement of spark" cost="1200" />
</mileage>
XSL-template
<xsl:template match="mileage[@value]">
<xsl:param name="sum" select="number(0)" />
<xsl:variable name="milinkage"><开发者_开发问答xsl:value-of select="number(repeating/@mileage)" /></xsl:variable>
<xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($sum)" /></xsl:apply-templates>
<xsl:value-of select="number(sum(.//@cost))"/> <!-- + number($sum) -->
</xsl:template>
Glued result is 18001200, but I want see 3000 (1800 + 1200) Please tell me what is wrong here?
Thanx!
Remove the dot and you will always see 3000 because all @costs (independent from starting point) will be summed.
<xsl:value-of select="number(sum(//@cost))"/> <!-- + number($sum) -->
Output will look like this: 30003000
But I assume that something is wrong with your approach. When you call a template recursive then the output will also will be printed as much as the template calls itself in your case. You need to print out the result at the end of your recursion
Given this input:
<root>
<mileage value="15000">
<operation title="Replacing the engine oil" cost="500" />
<sparepart title="Oil filter" cost="250" />
<sparepart title="Motor oil" cost="1050" />
</mileage>
<mileage value="30000">
<repeating mileage="15000" />
<operation title="Replacement of spark" cost="1200" />
</mileage>
</root>
and using this xslt:
<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:apply-templates select="root"/>
</xsl:template>
<xsl:template match="root">
<xsl:apply-templates select="mileage[@value=30000]"/>
</xsl:template>
<xsl:template match="mileage[@value]">
<xsl:param name="sum" select="number(0)" />
<xsl:variable name="milinkage"><xsl:value-of select="number(repeating/@mileage)" /></xsl:variable>
<xsl:variable name="newsum">
<xsl:value-of select="number(sum(.//@cost)) + $sum"/>
</xsl:variable>
<xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($newsum)" /></xsl:apply-templates>
<xsl:if test="not(parent::*/mileage[@value=$milinkage])">
<xsl:value-of select="$newsum"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
gives the correct result: 3000
You need xmlns:exsl="http://exslt.org/common"
<xsl:template match="/">
<xsl:variable name="nodes">
<xsl:apply-templates select="root/mileage[position()=last()]"/>
</xsl:variable>
<xsl:copy-of select="sum(exsl:node-set($nodes)/*[@cost]/@cost)"/>
</xsl:template>
<xsl:template match="mileage">
<xsl:copy-of select="*[@cost]"/>
<xsl:apply-templates select="../mileage[@value=current()/repeating/@mileage]"/>
</xsl:template>`
精彩评论