2016-09-20 139 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>