Xslt 将两个数相乘,然后求和
我很难尝试去做一些看起来应该很容易做的事情。我基本上想把一个节点上的2个数相乘,然后把所有节点上的2个数相加。这是我尝试过的XSLT代码Xslt 将两个数相乘,然后求和,xslt,xslt-1.0,xslt-2.0,Xslt,Xslt 1.0,Xslt 2.0,我很难尝试去做一些看起来应该很容易做的事情。我基本上想把一个节点上的2个数相乘,然后把所有节点上的2个数相加。这是我尝试过的XSLT代码 <xsl:value-of select="sum(Parts/Part/Quantity * Parts/Part/Rate)"/> 此代码导致一个错误,即“函数sum的参数1无法转换为节点集。” 有没有人知道我的错在哪里,或者我如何才能完成我想做的事情?以下是三种可能的解决方案: <parts> <part>
<xsl:value-of select="sum(Parts/Part/Quantity * Parts/Part/Rate)"/>
此代码导致一个错误,即“函数sum的参数1无法转换为节点集。”
有没有人知道我的错在哪里,或者我如何才能完成我想做的事情?以下是三种可能的解决方案:
<parts>
<part>
<rate>0.37</rate>
<quantity>10</quantity>
</part>
<part>
<rate>0.03</rate>
<quantity>10</quantity>
</part>
</parts>
<sales>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
</sales>
解决方案1 XSLT2:
当此转换应用于以下XML文档时:
<parts>
<part>
<rate>0.37</rate>
<quantity>10</quantity>
</part>
<part>
<rate>0.03</rate>
<quantity>10</quantity>
</part>
</parts>
<sales>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
</sales>
3.5
2.
0.75
0.80
0.90
3.5
2.
0.75
0.80
0.90
生成正确的结果:
<parts>
<part>
<rate>0.37</rate>
<quantity>10</quantity>
</part>
<part>
<rate>0.03</rate>
<quantity>10</quantity>
</part>
</parts>
<sales>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
<sale>
<price>3.5</price>
<quantity>2</quantity>
<Discount>0.75</Discount>
<Discount>0.80</Discount>
<Discount>0.90</Discount>
</sale>
</sales>
7560000000005
在最后一种情况下,对于每个销售
,我们计算价格
、数量
和所有可用(可变数量的)折扣
-s的乘积
是高阶函数的纯XSLT实现。在本例中,高阶函数
f:map()
用于映射每个sale
元素的子元素列表中的函数f:product()
。然后对结果进行求和以产生最终结果。Dimitre的所有解决方案都有效,他说得对,您不需要使用扩展函数,但有时它会使生活更轻松。它不会太有害,尤其是当您使用跨多个XSLT处理器支持的exslt扩展时。另外,出现序列错误的原因可能是因为您使用的是XSLT1处理器
如果要坚持使用所选的解决方案,则需要使用Saxon或其他支持XSLT2的XSLT处理器
否则,这里有一种在XSLT1中执行此操作的替代方法。这将适用于大多数XSLT处理器,有些人可能会发现它比递归版本更容易操作。就个人而言,我更喜欢递归版本(Dimitre的第三个建议),因为它更便于移植
<xsl:stylesheet version="1.0"
xmlns:ex="http://exslt.org/common"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template name="GetProducts">
<xsl:param name="left"/>
<xsl:param name="right"/>
<xsl:for-each select="$left/text()">
<product>
<xsl:value-of select="number(.) * number($right[position()])"/>
</product>
</xsl:for-each>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="products">
<xsl:call-template name="GetProducts">
<xsl:with-param name="left" select="Parts/Part/Rate"/>
<xsl:with-param name="right" select="Parts/Part/Quantity"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="sum(ex:node-set($products)/product)"/>
</xsl:template>
</xsl:stylesheet>
谢谢。解决方案#2正是我创建聚合乘法函数所需要的。@Baby程序员:谢谢您的欣赏!如果你喜欢这个,你会喜欢我博客上的很多东西:你应该提到足够的细节。。这样别人就可以想办法帮助你。。应该提到XSLT版本、处理器(saxon或其他)或@Least软件(Visual studio/Altova XML Spy)。。