我有一组xml节点,它们具有相同的节点名称,但有一个属性可以区分它们,还有一个数量属性:
<exampleNode typeOfnode="1" amount="100"/>
<exampleNode typeOfnode="1" amount="540"/>
<exampleNode typeOfnode="2" amount="200"/>
<exampleNode typeOfnode="2" amount="200"/>
<exampleNode typeOfnode="3" amount="10"/>
<exampleNode typeOfnode="3" amount="1"/>
<exampleNode typeOfnode="3" amount="110"/>
<exampleNode typeOfnode="3" amount="110"/>
<exampleNode typeOfnode="4" amount="110"/>
我正在使用递归模板来计算金额的总和,但只想对特定的typeOfNode执行此操作。这是我用来调用模板的代码:
<xsl:call-template name="addition">
<xsl:with-param name="currentValue">0</xsl:with-param>
<xsl:with-param name="counter"><xsl:value-of select="count(//exampleNode[@typeOfnode= '1'])"/></xsl:with-param>
<xsl:with-param name="typeOfnode">1</xsl:with-param>
</xsl:call-template>
<xsl:template name="addition">
<xsl:param name="currentValue"/>
<xsl:param name="counter"/>
<xsl:param name="typeOfNode"/>
<xsl:variable name="amount" select="//exampleNode[@typeOfNode = '$typeOfnode' and $counter]/@amount"/>
<xsl:variable name="recursiveValue" select="number($recursiveValue + $amount)"/>
<xsl:choose>
<xsl:when test="number($counter - 1) > 0">
<xsl:call-template name="addition">
<xsl:with-param name="currentValue">
<xsl:value-of select="$recursiveValue"/>
</xsl:with-param>
<xsl:with-param name="counter">
<xsl:value-of select="number($counter - 1)"/>
</xsl:with-param>
<xsl:with-param name="agreementType">
<xsl:value-of select="$agreementType"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$recursiveValue"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
通过使用XMLspy进行调试后,数量变量未被设置,我认为这是因为我搞砸了查询。任何人都知道我做错了什么?
答案 0 :(得分:0)
我没有查看代码的详细信息,为什么不简单地定义密钥
<xsl:key name="k1" match="exampleNode" use="@typeOfNode"/>
然后计算你使用的类型'1'节点的总和,例如
<xsl:value-of select="sum(key('k1', '1')/@amount)"/>
答案 1 :(得分:0)
快速回答,请参阅最后一个代码块。有关代码的一些注释,请从此处阅读。
如何通过使用currentValue iso recursiveValue为recursiveValue设置种子来修复递归循环:
<xsl:variable name="recursiveValue" select="number($currentValue + $amount)"/>
此处存在一些XSLT错误,例如这看起来不会起作用:
<xsl:variable name="amount" select="//exampleNode[@typeOfNode = '$typeOfnode' and $counter]/@amount"/>
如果你的意思是说“金额是$ counterOfNode = $ typeofnode的$ counter-th / exampleNode的@amount,那不是这样的。
您的代码段
<xsl:with-param name="agreementType">
<xsl:value-of select="$agreementType"/>
</xsl:with-param>
可能缺少一些混淆,你的意思是typeOfnode iso agreementType吗? :d
除此之外,还有更简单的解决方案。例如一个非常直接的:
<xsl:value-of select="sum(exampleNode[@typeOfnode='1']/@amount)"/>
答案 2 :(得分:0)
如果你真的,真的想要一个递归解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:call-template name="recurse">
<xsl:with-param name="nodes_to_sum" select="//exampleNode[@typeOfnode='1']"/>
<xsl:with-param name="sum" select="0"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="recurse">
<xsl:param name="nodes_to_sum"/>
<xsl:param name="sum"/>
<xsl:choose>
<xsl:when test="count($nodes_to_sum)=0">
<sum>
<xsl:value-of select="$sum"/>
</sum>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="recurse">
<xsl:with-param name="nodes_to_sum" select="$nodes_to_sum[position()>1]"/>
<xsl:with-param name="sum" select="$sum + $nodes_to_sum[1]/@amount"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
关于递归
在第一次调用中,我们初始化数据;整个集合 - 已经过滤 - 计算总和和初始总和(0)。
在递归'函数'中我们首先测试终端条件,在我们的例子中,“没有什么可以加起来”。如果是这种情况,请返回结果......
...否则,也就是说,如果还有更多工作要做,请使用较小的待办事项列表和较高的累加器来调用递归部分,这可以保证递归在某个时刻停止。
但请查看我的其他答案以获得更简单的解决方案......
答案 3 :(得分:0)
这里不需要递归!
事实上,想要的总和可以通过一个单行的XPath表达式返回:
sum(/*/*[@typeOfnode = $pType]/@amount)
这是一个完整的转型:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pType" select="3"/>
<xsl:template match="/">
<xsl:value-of select="sum(/*/*[@typeOfnode = $pType]/@amount)"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于以下XML文档(提供的片段,包装在单个顶部元素中):
<t>
<exampleNode typeOfnode="1" amount="100"/>
<exampleNode typeOfnode="1" amount="540"/>
<exampleNode typeOfnode="2" amount="200"/>
<exampleNode typeOfnode="2" amount="200"/>
<exampleNode typeOfnode="3" amount="10"/>
<exampleNode typeOfnode="3" amount="1"/>
<exampleNode typeOfnode="3" amount="110"/>
<exampleNode typeOfnode="3" amount="110"/>
<exampleNode typeOfnode="4" amount="110"/>
</t>
产生了想要的正确结果:
231