我有一些像这样的项目:
<item type="goods">
<quantity unit="pcs">172</quantity>
<unit-price currency="PLN">420</unit-price>
<VAT>7</VAT>
</item>
我想打印这些物品的总和。那么数学上是什么:
sum(quantity*unit-price)
我怎样才能用xsl做到这一点?我已经尝试使用for-each循环内部的变量和正常的valye-of。但我仍然得到一些奇怪的结果(我不会添加这个代码因为它很糟糕)。
答案 0 :(得分:10)
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/root">
<xsl:text>sum:</xsl:text>
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="item"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="sum">
<xsl:param name="nodes" />
<xsl:param name="sum" select="0" />
<xsl:variable name="current" select="$nodes[1]" />
<xsl:if test="$current">
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="$nodes[position() > 1]" />
<xsl:with-param name="sum" select="$sum + $current/quantity * $current/unit-price" />
</xsl:call-template>
</xsl:if>
<xsl:if test="not($current)">
<xsl:value-of select="$sum" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输入XML:
<root>
<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>
</root>
输出:
sum:20202
答案 1 :(得分:3)
除了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。使用transform-and-sum
1.x
<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"/>
<!-- to be applied on testTransform-and-sum5.xml -->
<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次”不需要实现显式递归,解决方案是紧凑的,并且完全消除了写入递归的潜在错误。
整体而言,总的开发时间,可读性和灵活性都得到了显着提升。