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>

我很难尝试去做一些看起来应该很容易做的事情。我基本上想把一个节点上的2个数相乘,然后把所有节点上的2个数相加。这是我尝试过的XSLT代码

<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)。。