1

下面的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 文档的预期答案是 8s(忽略格式):

<s><s><s><s><s><s><s><s><zero/></s></s></s></s></s></s></s></s> 我的想法是这样的,我可以有一个模板通过相加来对两个数字进行乘法运算。所以对于这个 2x2x2,我会做第 2 次 2 次第 3 次 2 返回 4,最后做 2*4。但是调用模板不会在 xslt 中返回值,这与 java 或方案不同,所以我感谢任何提示/帮助。

更新: 我通过在 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>
4

2 回答 2

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

说明

具有停止条件的原始递归——空参数节点集和累加器——用于将当前累加结果传递给下一个递归调用的参数。

于 2012-07-31T04:26:27.370 回答
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>

剩下的就是儿戏了……

于 2012-07-31T16:19:00.123 回答