2016-09-20 108 views
0

我只需要一些关于XSL基本功能的帮助。 我想显示先前计算的总金额。但我不知道该怎么做。 有关信息,XSL必须与我的技术限制XSLT 1.0一起使用。XSL - 计算金额之和

例如这里是我的xml。

<A> 
    <amount>10</amount> 
    <rate>4</rate> 
</A> 
<A> 
    <amount>-21</amount> 
    <rate>2</rate> 
</A> 
<B> 
    <amount>8</amount> 
    <rate>1</rate> 
</B> 
<C> 
    <amount>7</amount> 
    <rate>32</rate> 
</C> 

我想要显示Total元素中每个数量乘以每个关联速率的总和。

<Total value="230"> 
    <PositiveTotal> 
     272 
    </PositiveTotal> 
    <NegativeTotal> 
     -42 
    </NegativeTotal> 
</Total> 

我不知道该怎么做。

在此先感谢

问候,

+0

您的处理器是否支持XSLT 2.0? –

+0

你为什么不回答我的问题? –

+0

对不起,但我可以转移到XSLT 2.0 - 我必须使它适用于XSLT 1.0 – Luffy

回答

1

一个可能的多种解决方案。 它会给你一个想法,如何解决这个

<?xml version="1.0"?> 
<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:variable name="positiveTotal"> 
      <xsl:call-template name="sum"> 
       <xsl:with-param name="items" select="*[not(starts-with(amount,'-') or starts-with(rate, '-'))]"/> 
      </xsl:call-template> 
     </xsl:variable> 

     <xsl:variable name="negativTotal"> 
      <xsl:call-template name="sum"> 
       <xsl:with-param name="items" select="*[starts-with(amount,'-') or starts-with(rate, '-')]"/>     
      </xsl:call-template> 
     </xsl:variable> 

     <Total value="{$positiveTotal + $negativTotal}"> 
      <PositivTotal> 
       <xsl:value-of select="format-number($positiveTotal, '0')"/> 
      </PositivTotal> 
      <NegativeTotal> 
       <xsl:value-of select="format-number($negativTotal, '0')"/> 
      </NegativeTotal> 
     </Total> 

    </xsl:template> 

    <xsl:template name="sum"> 
     <xsl:param name="items" /> 
     <xsl:param name="total" select="0" /> 

     <xsl:choose> 
      <xsl:when test="not($items)"> 
       <xsl:value-of select="$total"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:call-template name="sum"> 
        <xsl:with-param name="items" select="$items[position() > 1]" /> 
        <xsl:with-param name="total" 
         select="$total + ($items[1]/amount * $items[1]/rate)" /> 
       </xsl:call-template> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

!!match="root"更改为您的根节点!鉴于source-xml无效。

已经有很多sum-问题!请参阅屏幕右侧的相关的框。

+0

非常感谢这个答案。它会帮助 - 我有一个额外的困难 - 请看我最后的评论 – Luffy

+0

不客气。如果您的问题得到解答,请关闭该问题。 [接受答案维基](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – uL1

0

这个问题已经被问了很多次,下面的链接到类似的搜索SO应该给你很多想法。

计算XSLT 2.0中计算值的总和是微不足道的,但在XSLT 1.0中并不容易,因为数据模型中没有这样的数据类型作为一组数字(sum()仅适用于一组节点)。可能的解决方案包括:

(a)递归模板调用,将运行总数作为参数提供给模板,添加下一个值,然后再次调用模板以使用新的运行总数处理列表的其余部分

(b)中的多相变换,其中所计算的值在一个相位放置在XML节点,以及使用该总和()函数在第二阶段中相加

(c)中使用其使用XSL的FXSL库:应用模板来模拟高阶函数,然后提供可以专门用于实现求和的折叠机制。

(d)呼唤扩展函数在过程编程语言

(e)中升级到XSLT 2.0。

0

我会建议你做这种方式:

XSLT 1。0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:template match="/root"> 
    <!-- first pass --> 
    <xsl:variable name="summands-rtf"> 
     <xsl:for-each select="*"> 
      <value> 
       <xsl:value-of select="amount * rate" /> 
      </value> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="summands" select="exsl:node-set($summands-rtf)/value" /> 
    <!-- output --> 
    <Total value="{sum($summands)}"> 
     <PositiveTotal> 
      <xsl:value-of select="sum($summands[. > 0])" /> 
     </PositiveTotal> 
     <NegativeTotal> 
      <xsl:value-of select="sum($summands[. &lt; 0])" /> 
     </NegativeTotal> 
    </Total> 
</xsl:template> 

</xsl:stylesheet> 

当应用于合式 XML输入(具有单个根元素):

XML

<root> 
    <A> 
    <amount>10</amount> 
    <rate>4</rate> 
    </A> 
    <A> 
    <amount>-21</amount> 
    <rate>2</rate> 
    </A> 
    <B> 
    <amount>8</amount> 
    <rate>1</rate> 
    </B> 
    <C> 
    <amount>7</amount> 
    <rate>32</rate> 
    </C> 
</root> 

结果将是:

<?xml version="1.0" encoding="UTF-8"?> 
<Total value="230"> 
    <PositiveTotal>272</PositiveTotal> 
    <NegativeTotal>-42</NegativeTotal> 
</Total>