2011-09-16 76 views
2

我使用xml和PHP創建了一個發票管理系統,但最新的PHP版本不支持XSLT 2.0 - 因此我必須尋找sum()方法。如何將有效的xslt 2函數「sum(unitprice * quantity)」轉換爲xslt 1.0?xslt 1和求和函數

的XML的東西是基於John's Examples

我的節點集嘗試過,但它不支持:

+0

問得好。 XPath 2.0(單個XPath表達式)最容易實現,XSLT 1.0(手寫遞歸模板或使用FXSL庫的便捷模板/函數)涉及更多的解決方案。 –

回答

6

其實,sum(price*quantity)是無效的XSLT 2.0語法。我想你的意思是`sum(對於$ x in * return $ x/price * $ x/quantity)。

在XSLT 1.0求和計算值可以通過以下方式來完成:

  • 兩遍溶液中,創建一個節點集合,其中所述節點保持所計算的值,則在所述節點求和-set

  • 遞歸溶液:寫,到目前爲止作爲參數的總傳遞遞歸模板,添加合計量*爲當前節點,則遞歸處理剩餘節點

  • 高階SOLUT離子:使用Dimitre Novatchev的FXSL庫

  • 擴展解決方案:使用擴展函數等撒克遜:總和()

+0

很好的答案!非常感謝!!我使用了第二種解決方案(http://stackoverflow.com/questions/436998/multiply-2-numbers-and-then-sum-with-xslt) – NaN

1

您可以簡單地創建一個模板「xmlXPathCompOpEval功能節點集合中找不到」 sumNumbers添加兩個數量。除了可以在select語句來執行:

<xsl:template name="sumNumbers"> 
    <xsl:param name="num1"/> 
    <xsl:param name="num2"/> 

    <xsl:value-of select="$num1 + $num2" /> 
</xsl:template> 

應該工作

+0

嗯......是的:然後就是這樣! – IcedDante

+0

如何在節點集上運行? – LarsH

1

在XSLT 1.0可以使用FXSLmap()功能/模板(和任一FXSL的sum()功能或標準的XPath sum())函數,如圖以下示例:

有了這個XML文檔

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

我們想從所有的銷售得到的總和 - 這是產品的總和:price* quantity * discount1 * discount2 ...* discountN每個銷售。

這XSLT 1.0轉化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net/" 
xmlns:ext="http://exslt.org/common" 
xmlns:test-map-product="test-map-product" 
exclude-result-prefixes="xsl f ext test-map-product" 
> 
    <xsl:import href="sum.xsl"/> 
    <xsl:import href="map.xsl"/> 
    <xsl:import href="product.xsl"/> 

    <!-- This transformation is to be applied on: 
     salesMap.xml 

     It contains the code of the "sum of products" from the 
     article "The Functional Programming Language XSLT" 
    --> 

    <test-map-product:test-map-product/> 

    <xsl:output method="text"/> 

    <xsl:template match="/"> 
    <!-- Get: map product /sales/sale --> 
    <xsl:variable name="vSalesTotals"> 
     <xsl:variable name="vTestMap" select="document('')/*/test-map-product:*[1]"/> 
     <xsl:call-template name="map"> 
      <xsl:with-param name="pFun" select="$vTestMap"/> 
      <xsl:with-param name="pList1" select="/sales/sale"/> 
     </xsl:call-template> 
    </xsl:variable> 

    <!-- Get sum map product /sales/sale --> 
     <xsl:call-template name="sum"> 
     <xsl:with-param name="pList" select="ext:node-set($vSalesTotals)/*"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="makeproduct" mode="f:FXSL" 
     match="test-map-product:*"> 
     <xsl:param name="arg1"/> 

     <xsl:call-template name="product"> 
     <xsl:with-param name="pList" select="$arg1/*"/> 
     </xsl:call-template> 
    </xsl:template> 
</xsl:stylesheet> 

當上述XML文檔被應用時產生有用的,正確的結果

7.5600000000000005 

II。 XPath 2.0解決方案

簡化問題(最初發布的問題)可以使用簡單的XPath 2.0單線解決。如果我們有這個XML文檔:

<sales> 
    <sale> 
    <price>3.5</price> 
    <quantity>2</quantity> 
    </sale> 
    <sale> 
    <price>3.5</price> 
    <quantity>2</quantity> 
    </sale> 
</sales> 

那麼這個XPath 2.0表達式

sum(/*/sale/(price*quantity)) 

評估時產生的有用之

14 

這裏是一個基於XSLT 2.0的此事實驗證:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <xsl:sequence select="sum(sale/(price*quantity))"/> 
</xsl:template> 
</xsl:stylesheet> 

當在XML文檔上面,有用,正確的結果產生進行這種轉變:+1

14