我正在尝试理解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中遗漏了一些边缘案例吗?
为了说清楚,这不是一个功课问题。我只是想通过一个简单的例子来理解差异(如果有的话)。
答案 0 :(得分:4)
是的,这两个标本似乎相同。通常,您不需要在XSLT中进行递归,除非序列中的一个项目的处理在某种程度上取决于先前项目的处理。如果每个项目都独立于其他项目进行处理,那么您可以使用过滤器表达式或映射表达式,其中xsl:for-each是一个示例。以这种方式执行此操作(除了代码的可读性之外)的一个优点是,您不会强制执行处理顺序,这使优化器可以更自由地发挥其魔力。
答案 1 :(得分:1)
这两个版本是否相同? (我的测试表明如此)。我 在Ver.2中遗漏了一些边缘案例?
他们似乎产生相同的结果 - 很难说,因为两个代码段都不必要地复杂。
这可以通过:
完成<xsl:sequence select="$values[matches(., $pattern)]"/>