10

如何保存 xsl:for-each 中发生的迭代?(XSL 中的变量是不可变的)

我的目标是找到特定级别的任何节点的最大子节点数。

例如,我可能想打印此调查中任何问题的响应节点不超过 2 个:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="testing.xsl"?>
<Survey>
  <Question>
    <Response text="Website" />
    <Response text="Print Ad" />
  </Question>
  <Question>
    <Response text="Yes" />
  </Question>
</Survey>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
  <html>
  <head>
  </head>
  <body>
    <xsl:for-each select="Survey">
      The survey has <xsl:value-of select="count(child::Question)"/> questions.  
      <br />
      <xsl:variable name="counter">0</xsl:variable>
      <xsl:for-each select="Question">
        <!-- TODO: increment the counter ??????? -->
      </xsl:for-each>
      No more than <xsl:value-of select="$counter"/> responses were returned for any question.
    </xsl:for-each>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>
4

1 回答 1

10

不会“保存 xsl:for-each 中发生的迭代”,因为XSLT 是一种函数式语言并且变量是不可变的。

以下变换找到所需的最大值:

<xsl:stylesheet 版本="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:输出方法="文本"/>

    <xsl:模板匹配="/">
      <xsl:call-template name="最大值">
        <xsl:with-param name="pNodes" select="*/Question"/>
      </xsl:调用模板>
    </xsl:模板>

    <xsl:template name="最大">
      <xsl:param name="pNodes"/>

      <xsl:variable name="vNumNodes" select="count($pNodes)"/>

      <xsl:选择>
        <xsl:when test="$vNumNodes = 1">
          <xsl:value-of select="count($pNodes[1]/Response)"/>
        </xsl:when>
        <xsl:否则>
          <xsl:变量名="vHalf"
               select="floor($vNumNodes div 2)"/>

          <xsl:变量名="vMax1">
           <xsl:call-template name="最大值">
            <xsl:with-param name="pNodes"
                 select="$pNodes[not(position() > $vHalf)]"/>
           </xsl:调用模板>
          </xsl:变量>

          <xsl:变量名="vMax2">
           <xsl:call-template name="最大值">
            <xsl:with-param name="pNodes"
                 select="$pNodes[位置() > $vHalf]"/>
           </xsl:调用模板>
          </xsl:变量>

          <xsl:value-of 选择=
           "$vMax1*($vMax1 >= $vMax2) + $vMax2*($vMax2 > $vMax1)"/>
        </xsl:否则>
      </xsl:选择>
    </xsl:模板>
</xsl:样式表>

应用于提供的 XML 文档时:

<调查>
    <问题>
        <响应文本="网站" />
        <响应文本="平面广告" />
    </问题>
    <问题>
        <响应文本=“是” />
    </问题>
</调查>

产生了想要的结果:

2

请注意以下几点:名为“ ”的模板以maximum递归方式调用自身并实现DVC(分治原则) 以最小化递归堆栈深度。节点列表被分成两个,计算两个列表的最大值(递归)并返回两者中较大的一个。

于 2008-12-04T00:56:04.993 回答