除了Kirill的正确答案之外,还可以使用以下XPath 2.0(XSLT 2.0)解决方案:从任何支持XPath 2.0的语言中使用以下单个XPath 2.0表达式:
sum((quantity*unit-price))
以下是一个完整的示例,使用XSLT 2.0作为XPath 2.0的宿主:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select="sum(/*/*/(quantity*unit-price))"/>
</xsl:template>
</xsl:stylesheet>
当应用于以下 XML 文档时:
<items>
<item type="goods">
<quantity unit="pcs">1</quantity>
<unit-price currency="PLN">2</unit-price>
<VAT>7</VAT>
</item>
<item type="goods">
<quantity unit="pcs">10</quantity>
<unit-price currency="PLN">20</unit-price>
<VAT>7</VAT>
</item>
<item type="goods">
<quantity unit="pcs">100</quantity>
<unit-price currency="PLN">200</unit-price>
<VAT>7</VAT>
</item>
</items>
所需的正确结果已生成:
20202
II. 使用 FXSL 1.x 的 transform-and-sum
模板/函数的 XSLT 1.0 解决方案
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:func-transform="f f:func-transform"
exclude-result-prefixes="xsl func-transform"
>
<xsl:import href="transform-and-sum.xsl"/>
<xsl:output method="text"/>
<func-transform:func-transform/>
<xsl:template match="/">
<xsl:call-template name="transform-and-sum">
<xsl:with-param name="pFuncTransform"
select="document('')/*/func-transform:*[1]"/>
<xsl:with-param name="pList" select="/*/*"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="func-transform:*" mode="f:FXSL">
<xsl:param name="arg1" select="0"/>
<xsl:value-of select="$arg1/quantity * $arg1/unit-price "/>
</xsl:template>
</xsl:stylesheet>
当在同一XML文档(上述)上应用此转换时,将产生相同的正确结果:
20202
请注意:使用FXSL,您无需实现“第N次”明确递归,解决方案紧凑,完全消除了编写递归时潜在的错误。
总体而言,总开发时间、可读性和灵活性都得到了显著改善。