我一直试图获得用户在产品上花费的总金额,但没有成功。给定以下XML示例,客户1花费的总金额将是21,00,但我得到10,50(这只发生在客户多次购买相同产品时,如果他购买不同的产品,返回金额是预期的)
XML示例:
<root>
<sale id="1">
<date>2014-01-01</date>
<client>1</client>
</sale>
<sale id="2">
<date>2014-01-02</date>
<client>1</client>
</sale>
<sale_details saleID="1">
<product id="1"/>
</sale_details>
<sale_details saleID="2">
<product id="1"/>
</sale_details>
<product_details productID="1">
<name>product x</name>
<price>10.50</price>
</product_details>
<product_details productID="2">
<name>product x</name>
<price>5.26</price>
</product_details>
<client_detail clientID="1">
<name>client 1</name>
</client_detail>
<client_detail clientID="2">
<name>client 2</name>
</client_detail>
</root>
XSLT示例:
<xsl:template name="sum-spent-amount">
<xsl:param name="clientID"/>
<xsl:value-of select="sum(//gv:product_details[@productID=//gv:sale_details[@saleID=//gv:sale[gv:client=$clientID]/@id]/gv:product/@id]/gv:price)"/>
</xsl:template>
提前感谢!
当然,您得到的结果是10.5:您正在对已售出产品的唯一实例求和。你必须把实际销售的价格加起来。这里有一种方法:
XSLT 1.0<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="clientID" select="1"/>
<xsl:key name="sale-by-clientID" match="sale" use="client" />
<xsl:key name="sale_detail-by-saleID" match="sale_details" use="@saleID" />
<xsl:key name="product-by-id" match="product_details" use="@productID" />
<xsl:template match="/">
<xsl:variable name="mySaleIDs" select="key('sale-by-clientID', $clientID)/@id" />
<xsl:variable name="prices">
<xsl:for-each select="key('sale_detail-by-saleID', $mySaleIDs)">
<price><xsl:value-of select="key('product-by-id', product/@id)/price"/></price>
</xsl:for-each>
</xsl:variable>
<sum><xsl:value-of select="sum(exsl:node-set($prices)/price)"/></sum>
</xsl:template>
</xsl:stylesheet>
当这被应用到你的输入时,结果是:
<?xml version="1.0" encoding="UTF-8"?>
<sum>21</sum>
我使用递归模板得到了这个解决方案:
模板:
<xsl:template name="sum">
<xsl:param name="nodes"/>
<xsl:param name="total" select="0"/>
<xsl:variable name="current" select="$nodes[1]" />
<xsl:choose>
<xsl:when test="$current">
<xsl:variable name="product" select="//gv:product_details[@productID=$current/gv:product/@id]"/>
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
<xsl:with-param name="total" select="$total + $product/gv:price"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise><xsl:value-of select="$total"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
此处使用模板:
<xsl:variable name="clientID" select="1"/>
<xsl:call-template name="sum">
<xsl:with-param name="nodes" select="//gv:sale_details[@saleID=//gv:sale[gv:client=clientID]/@id]" />
</xsl:call-template>