0

我试图了解 XSL 对 for-each 的处理。最初,我编写了一个递归选择值函数(过滤掉所有与正则表达式模式不匹配的字符串),如下所示:

<!-- Ver.1 -->
<xsl:function name="choose-values">
  <xsl:param name="values" />
  <xsl:param name="pattern" as="xs:string" />

  <xsl:choose>
    <xsl:when test="count($values) = 0" >
      <xsl:sequence select="()" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:variable name="tail"
                    select="choose-values(subsequence($values, 2), $pattern)" />
      <xsl:variable name="value" select="$values[1]" />
      <xsl:sequence select="if (matches($value, $pattern))
                            then ($value, $tail)
                            else $tail" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>

然后我偶然发现<xsl:for-each>并重写如下:

<!-- Ver.2 -->
<xsl:function name="choose-values">
  <xsl:param name="values" />
  <xsl:param name="pattern" as="xs:string" />

  <xsl:for-each select="$values">
      <xsl:if test="matches(., $pattern)">
        <xsl:sequence select="." />
      </xsl:if>
  </xsl:for-each>
</xsl:function>

这两个版本是等价的吗?(我的测试表明如此)。我错过了 Ver.2 中的一些边缘情况吗?

只是为了让事情清楚,这不是一个家庭作业问题。我只是想通过一个简单的例子来理解差异(如果有的话)。

4

2 回答 2

4

是的,这两个样本似乎是等价的。通常,您不需要在 XSLT 中进行递归,除非序列中一项的处理以某种方式依赖于先前项的处理。如果每个项目都独立于其他项目进行处理,那么您可以使用过滤器表达式或映射表达式,其中 xsl:for-each 就是一个示例。这样做的一个优点(除了代码的可读性)是您不会强加处理顺序,这给了优化器更多的自由来发挥它的魔力。

于 2011-10-16T14:56:54.290 回答
1

这两个版本是等价的吗?(我的测试表明如此)。我错过了 Ver.2 中的一些边缘情况吗?

它们似乎产生了相同的结果——很难说,因为两个代码片段都不必要地复杂。

这可以简单地通过

<xsl:sequence select="$values[matches(., $pattern)]"/>
于 2011-10-16T14:52:37.927 回答