標籤:

XSLT來總結的兩個屬性的產品

XSLT來總結的兩個屬性的產品 xslt xpath 總和sum我有下面的XML源結構:

<turnovers> <turnover repid="1" amount="500" rate="0.1"/> <turnover repid="5" amount="600" rate="0.5"/> <turnover repid="4" amount="400" rate="0.2"/> <turnover repid="1" amount="700" rate="0.05"/> <turnover repid="2" amount="100" rate="0.15"/> <turnover repid="1" amount="900" rate="0.25"/> <turnover repid="2" amount="1000" rate="0.18"/> <turnover repid="5" amount="200" rate="0.55"/> <turnover repid="9" amount="700" rate="0.40"/></turnovers>

我需要一個XSL:value-of的選擇,將返回的速度屬性的乘積的總和,並對於給定的代表ID的數量的屬性。因此,對於代表5我需要((600×0.5)+(200×0.55))。本文地址 :CodeGo.net/77996/ -------------------------------------------------------------------------------------------------------------------------1.

<xsl:stylesheet version="1.0" xmlns:xsl=" CodeGo.net > <xsl:template match="/turnovers"> <val> <!-- call the sum function (with the relevant nodes) --> <xsl:call-template name="sum"> <xsl:with-param name="nodes" select="turnover[@repid="5"]" /> </xsl:call-template> </val> </xsl:template> <xsl:template name="sum"> <xsl:param name="nodes" /> <xsl:param name="sum" select="0" /> <xsl:variable name="curr" select="$nodes[1]" /> <!-- if we have a node, calculate & recurse --> <xsl:if test="$curr"> <xsl:variable name="runningsum" select=" $sum + $curr/@amount * $curr/@rate " /> <xsl:call-template name="sum"> <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]" /> <xsl:with-param name="sum" select="$runningsum" /> </xsl:call-template> </xsl:if> <!-- if we don"t have a node (last recursive step), return sum --> <xsl:if test="not($curr)"> <xsl:value-of select="$sum" /> </xsl:if> </xsl:template></xsl:stylesheet>

給出:

<val>410</val>

<xsl:if>S可通過一個單一的可替換<xsl:choose>。遞歸這個過程中少了一個檢查,但它的代碼另外兩行。2. 以純XSLT 1.0你需要一個遞歸模板這一點,例如:

<xsl:template match="turnovers"> <xsl:variable name="selectedId" select="5" /> <xsl:call-template name="sum_turnover"> <xsl:with-param name="turnovers" select="turnover[@repid=$selectedId]" /> </xsl:call-template> </xsl:template> <xsl:template name="sum_turnover"> <xsl:param name="total" select="0" /> <xsl:param name="turnovers" /> <xsl:variable name="head" select="$turnovers[1]" /> <xsl:variable name="tail" select="$turnovers[position()>1]" /> <xsl:variable name="calc" select="$head/@amount * $head/@rate" /> <xsl:choose> <xsl:when test="not($tail)"> <xsl:value-of select="$total + $calc" /> </xsl:when> <xsl:otherwise> <xsl:call-template name="sum_turnover"> <xsl:with-param name="total" select="$total + $calc" /> <xsl:with-param name="turnovers" select="$tail" /> </xsl:call-template> </xsl:otherwise> </xsl:choose> </xsl:template>

3. 這應該做的伎倆,你需要做進一步的工作來選擇不同的repid

<xsl:stylesheet version="2.0" xmlns:xsl=" CodeGo.net <xsl:template match="/"> <xsl:variable name="totals"> <product> <xsl:for-each select="turnovers/turnover"> <repid repid="{@repid}"> <value><xsl:value-of select="@amount * @rate"/></value> </repid> </xsl:for-each> </product> </xsl:variable> <totals> <total repid="5" value="{sum($totals/product/repid[@repid="5"]/value)}"/> </totals> </xsl:template></xsl:stylesheet>

4. 在XSLT 1.0 FXSL使得這樣的問題很容易解決:

<xsl:stylesheet version="1.0" xmlns:xsl=" CodeGo.net xmlns:f=" CodeGo.net xmlns:ext=" CodeGo.net exclude-result-prefixes="xsl f ext" > <xsl:import href="zipWith.xsl"/> <xsl:output method="text"/> <xsl:variable name="vMultFun" select="document("")/*/f:mult-func[1]"/> <xsl:template match="/"> <xsl:call-template name="profitForId"/> </xsl:template> <xsl:template name="profitForId"> <xsl:param name="pId" select="1"/> <xsl:variable name="vrtfProducts"> <xsl:call-template name="zipWith"> <xsl:with-param name="pFun" select="$vMultFun"/> <xsl:with-param name="pList1" select="/*/*[@repid = $pId]/@amount"/> <xsl:with-param name="pList2" select="/*/*[@repid = $pId]/@rate"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="sum(ext:node-set($vrtfProducts)/*)"/> </xsl:template> <f:mult-func/> <xsl:template match="f:mult-func" mode="f:FXSL"> <xsl:param name="pArg1"/> <xsl:param name="pArg2"/> <xsl:value-of select="$pArg1 * $pArg2"/> </xsl:template></xsl:stylesheet>

當這種轉變是應用在最初發布源XML正確的結果產生: 310 在XSLT 2.0 FXSL 2.0可以通過一個XPath的一行來表示:

sum(f:zipWith(f:multiply(), /*/*[xs:decimal(@repid) eq 1]/@amount/xs:decimal(.), /*/*[xs:decimal(@repid) eq 1]/@rate/xs:decimal(.) ) )

整個transform:

<xsl:stylesheet version="2.0" xmlns:xsl=" CodeGo.net xmlns:xs=" CodeGo.net xmlns:f=" CodeGo.net exclude-result-prefixes="f xs"> <xsl:import href="../f/func-zipWithDVC.xsl"/> <xsl:import href="../f/func-Operators.xsl"/> <!-- To be applied on testFunc-zipWith4.xml --> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/"> <xsl:value-of select= "sum(f:zipWith(f:multiply(), /*/*[xs:decimal(@repid) eq 1]/@amount/xs:decimal(.), /*/*[xs:decimal(@repid) eq 1]/@rate/xs:decimal(.) ) ) "/> </xsl:template></xsl:stylesheet>

同樣,這種轉變會產生正確答案: 310 請注意以下幾點:該f:zipWith()函數接受一個函數fun()(中具有長項兩個兩個列表。它產生的長度一個新的列表,其項目是成對應用的結果fun()在相應的k個兩表中的項目。f:zipWith()在表達式取函數f:multiply()和對應的兩個序列「ammount「和」rate「屬性。的sesult是一個序列,其中每個項是對應的商品」ammount「和」rate「。 最後 CodeGo.net,這個序列的總和產生。 有沒有必要寫一個明確的遞歸,它也保證了幕後場景內f:zipWith()永遠不會崩潰(適用於所有的實際情況)與「堆棧溢出」5.

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl=" CodeGo.net xmlns:xs=" CodeGo.net exclude-result-prefixes="xs" version="2.0"> <xsl:variable name="repid" select="5" /> <xsl:template match="/"> <xsl:value-of select= "sum(for $x in /turnovers/turnover[@repid=$repid] return $x/@amount * $x/@rate)"/> </xsl:template></xsl:stylesheet>

你可以這樣做,如果你只是需要的價值,而不是XML。6. 要做到這一點XSLT中最簡單的方法可能是編程語言綁定,這樣你可以定義自己的XPath函數。本文標題 :XSLT來總結的兩個屬性的產品本文地址 :CodeGo.net/77996/
推薦閱讀:

知識總結丨原核生物知識點匯總
中國歷代禁書題解(詩涇)孔子刪定編纂(我國第一部詩歌總結)
必修4第五講:『把握思維的奧妙』知識點總結 習題精練
兒科醫生診療幼兒急疹經驗總結
一句話總結各種食物相剋,吃貨們要小心啦!

TAG:產品 | 總結 |