2011-08-12 94 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