我有嵌套的 xml 数据。我正在循环项目元素,并希望使用递归获得所有项目的价格总和。
<?xml version="1.0" encoding="utf-8"?>
<order>
<item>
<name>Product A</name>
<price>10.00</price>
<item>
<name>Product B</name>
<price>5.00</price>
<item>
<name>Sub-Product 1</name>
<price>2.00</price>
</item>
</item>
</item>
<item>
<name>Product 2</name>
<price>2.00</price>
</item>
</order>
我看到循环时不考虑最后一个项目元素。我不确定我错过了什么。
`<!-- Recursive template to calculate the sum of prices -->
<xsl:template name="sumPrices">
<xsl:param name="items"/>
<xsl:param name="sum"/>
<!-- Iterate over each item -->
<xsl:for-each select="$items">
<!-- Add the price of the current item to the sum -->
<xsl:variable name="currentPrice" select="number($items/price)"/>
<xsl:variable name="newSum" select="$sum + $currentPrice"/>
<!-- Recursive call for sub-items -->
<xsl:call-template name="sumPrices">
<xsl:with-param name="items" select="item"/>
<xsl:with-param name="sum" select="$newSum"/>
</xsl:call-template>
</xsl:for-each>
<!-- Output the total sum -->
<xsl:if test="not($items)">
<total>
<xsl:value-of select="$sum"/>
</total>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我不确定我错过了什么。
当您没有向我们展示模板的初始调用时,很难说您错过了什么,因此我们无法重现您的问题。
无论如何,都不需要递归。您可以简单地使用:
<xsl:value-of select="sum(//item/price)"/>
返回所有商品价格的总和,无论它们在输入 XML 层次结构中的位置如何。
如果出于某种原因,您想使用递归,那么可以这样做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<total>
<xsl:call-template name="sumPrices">
<xsl:with-param name="items" select="//item"/>
</xsl:call-template>
</total>
</xsl:template>
<xsl:template name="sumPrices">
<xsl:param name="items"/>
<xsl:param name="sum" select="0"/>
<xsl:choose>
<xsl:when test="$items">
<xsl:variable name="currentPrice" select="$items[1]/price"/>
<!-- recursive call -->
<xsl:call-template name="sumPrices">
<xsl:with-param name="items" select="$items[position() > 1]"/>
<xsl:with-param name="sum" select="$sum + $currentPrice"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$sum"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
但是,没有理由这样做。