2011-08-12 95 views
0

當我嘗試遞歸和從多個節點的屬性,它的膠樣串:(XSLT遞歸和煩惱


XML文件(第二里程節點包括第一里程節點)

<mileage value="15000"> 
    <operation title="Replacing the engine oil" cost="500" /> 
    <sparepart title="Oil filter" cost="250" /> 
    <sparepart title="Motor oil" cost="1050" /> 
</mileage> 
<mileage value="30000"> 
    <repeating mileage="15000" /> 
    <operation title="Replacement of spark" cost="1200" /> 
</mileage> 

XSL模板

<xsl:template match="mileage[@value]"> 
    <xsl:param name="sum" select="number(0)" /> 
    <xsl:variable name="milinkage"><xsl:value-of select="number(repeating/@mileage)" /></xsl:variable> 
    <xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($sum)" /></xsl:apply-templates> 
    <xsl:value-of select="number(sum(.//@cost))"/> <!-- + number($sum) --> 
</xsl:template> 

膠合結果是18001200,但我想看3000(1800 + 1200) 請告訴我這裏有什麼問題嗎?

Thanx!

+0

對不起,這是我的第一篇文章stackoverflow。 – Yuri

+0

我編輯了我的答案。希望這能解決你的問題。 – therealmarv

回答

0

您需要的xmlns:exsl = 「http://exslt.org/common」

<xsl:template match="/"> 
    <xsl:variable name="nodes"> 
     <xsl:apply-templates select="root/mileage[position()=last()]"/> 
    </xsl:variable> 
    <xsl:copy-of select="sum(exsl:node-set($nodes)/*[@cost]/@cost)"/> 
</xsl:template> 

<xsl:template match="mileage"> 
    <xsl:copy-of select="*[@cost]"/> 
    <xsl:apply-templates select="../mileage[@value=current()/repeating/@mileage]"/> 
</xsl:template>` 
+0

** @ A。哈吉**,thanx,但可以重複,並有幾個程度的嵌套。例如:'<里程值=「45000」><重複里程=「30000」/>'這裏我們有兩次在標籤上持有:先進入米蘭=「30000」,然後從他的米雷= 15000" 。 現在我不明白一個遞歸模板如何累加一個變量和返回它已經總結。 用「cost」創建一個包含屬性的所有元素的臨時樹節點可能是正確的嗎? – Yuri

+0

@Yuri,可能是臨時樹realy將是最好的解決方案。我更新了我的代碼。 –

0

刪除的點,你會經常看到3000,因爲所有@costs(獨立於起點)將彙總。

<xsl:value-of select="number(sum(//@cost))"/> <!-- + number($sum) --> 

輸出看起來就像這樣:30003000

但我認爲什麼是錯的你的方法。當你遞歸調用一個模板時,輸出也將被打印,就像模板在你的情況下調用它自己一樣。您需要在您的遞歸

年底鑑於此輸入打印出來的結果是:

<root> 
<mileage value="15000"> 
    <operation title="Replacing the engine oil" cost="500" /> 
    <sparepart title="Oil filter" cost="250" /> 
    <sparepart title="Motor oil" cost="1050" /> 
</mileage> 
<mileage value="30000"> 
    <repeating mileage="15000" /> 
    <operation title="Replacement of spark" cost="1200" /> 
</mileage> 
</root> 

,並使用此XSLT:

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

<xsl:template match="/"> 
    <xsl:apply-templates select="root"/> 
</xsl:template> 

<xsl:template match="root"> 
    <xsl:apply-templates select="mileage[@value=30000]"/> 
</xsl:template> 

<xsl:template match="mileage[@value]"> 
    <xsl:param name="sum" select="number(0)" /> 
    <xsl:variable name="milinkage"><xsl:value-of select="number(repeating/@mileage)" /></xsl:variable> 
    <xsl:variable name="newsum"> 
     <xsl:value-of select="number(sum(.//@cost)) + $sum"/> 
    </xsl:variable> 
    <xsl:apply-templates select="parent::*/mileage[@value=$milinkage]"><xsl:with-param name="sum" select="number($newsum)" /></xsl:apply-templates> 
    <xsl:if test="not(parent::*/mileage[@value=$milinkage])"> 
     <xsl:value-of select="$newsum"/> 
    </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

給出正確的結果:3000