下面的xml文档代表3个数字,2,2和2.节点<s>
被计为数字,并以<zero/>
结束。
<?xml version="1.0" encoding="UTF-8"?>
<nat xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="nat.xsd">
<s>
<s>
<zero/>
</s>
</s>
<s>
<s>
<zero/>
</s>
</s>
<s>
<s>
<zero/>
</s>
</s>
</nat>
我刚开始学习xslt,这是递归练习之一。我可以递归地加上所有数字,但这个乘以两个以上的数字只会让我大吃一惊。我不知道该怎么做。
上述xml doc的预期答案是8s(忽略格式):
<s><s><s><s><s><s><s><s><zero/></s></s></s></s></s></s></s></s>
我的想法是这样的,我可以通过添加模板来为两个数字进行乘法运算。因此,对于这个2x2x2,我会做第2次2次,返回4,最后做2 * 4。但是调用模板不会在xslt中返回值,这与java或scheme不同,所以我感谢任何提示/帮助。
更新 我通过在Dimitre的回答中添加打印模板得到了我的答案。这是:
<xsl:template name="print">
<xsl:param name="pAccum"/>
<xsl:choose>
<xsl:when test="$pAccum > 0">
<s>
<xsl:call-template name="print">
<xsl:with-param name="pAccum" select="$pAccum - 1"/>
</xsl:call-template>
</s>
</xsl:when>
<xsl:otherwise>
<zero/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:call-template name="product">
<xsl:with-param name="pArgs" select="//zero"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="product">
<xsl:param name="pAccum" select="1"/>
<xsl:param name="pArgs" select="/.."/>
<xsl:choose>
<xsl:when test="not($pArgs)">
<xsl:value-of select="$pAccum"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="product">
<xsl:with-param name="pAccum"
select="$pAccum * count($pArgs[1]/ancestor::s)"/>
<xsl:with-param name="pArgs" select="$pArgs[position() > 1]"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<nat>
<s>
<s>
<zero/>
</s>
</s>
<s>
<s>
<zero/>
</s>
</s>
<s>
<s>
<zero/>
</s>
</s>
</nat>
会产生想要的正确结果:
8
<强>解释强>:
带有停止条件的原始递归 - 空参数node-set和accumulator - 用于将当前累积结果传递给下一个递归调用的参数。
答案 1 :(得分:1)
在XSLT 2.0中,我将从一对函数开始:
<xsl:function name="f:toNumber" as="xs:integer">
<xsl:param name="z" as="element(zero)"/>
<xsl:sequence select="count($z/ancestor::*)"/>
</xsl:function>
<xsl:function name="f:fromNumber" as="element()>
<xsl:param name="z" as="xs:integer"/>
<xsl:choose>
<xsl:when test="$z=0"><zero/></xsl:when>
<xsl:otherwise><s><xsl:sequence select="f:fromNumber($z - 1)"/>
</xsl:function>
解决数字表示的奇怪问题。
现在你只需要一个计算一系列数字乘积的函数:
<xsl:function name="f:product" as="xs:integer">
<xsl:param name="in" as="xs:integer"/>
<xsl:sequence select="if (count($in) = 1) then $in[1] else $in * f:product($in[position()>1])"/>
</xsl:function>
其余的是孩子的游戏......