我使用xml和PHP創建了一個發票管理系統,但最新的PHP版本不支持XSLT 2.0 - 因此我必須尋找sum()方法。如何將有效的xslt 2函數「sum(unitprice * quantity)」轉換爲xslt 1.0?xslt 1和求和函數
的XML的東西是基於John's Examples
我的節點集嘗試過,但它不支持:
我使用xml和PHP創建了一個發票管理系統,但最新的PHP版本不支持XSLT 2.0 - 因此我必須尋找sum()方法。如何將有效的xslt 2函數「sum(unitprice * quantity)」轉換爲xslt 1.0?xslt 1和求和函數
的XML的東西是基於John's Examples
我的節點集嘗試過,但它不支持:
其實,sum(price*quantity)
是無效的XSLT 2.0語法。我想你的意思是`sum(對於$ x in * return $ x/price * $ x/quantity)。
在XSLT 1.0求和計算值可以通過以下方式來完成:
兩遍溶液中,創建一個節點集合,其中所述節點保持所計算的值,則在所述節點求和-set
遞歸溶液:寫,到目前爲止作爲參數的總傳遞遞歸模板,添加合計量*爲當前節點,則遞歸處理剩餘節點
高階SOLUT離子:使用Dimitre Novatchev的FXSL庫
擴展解決方案:使用擴展函數等撒克遜:總和()
很好的答案!非常感謝!!我使用了第二種解決方案(http://stackoverflow.com/questions/436998/multiply-2-numbers-and-then-sum-with-xslt) – NaN
在XSLT 1.0可以使用FXSL的map()
功能/模板(和任一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
問得好。 XPath 2.0(單個XPath表達式)最容易實現,XSLT 1.0(手寫遞歸模板或使用FXSL庫的便捷模板/函數)涉及更多的解決方案。 –