【问题标题】:How to do a "while"-like loop in XSLT?如何在 XSLT 中执行类似“while”的循环?
【发布时间】:2012-06-23 01:40:42
【问题描述】:

我是 XSLT 的新手,我在这个问题上遇到了很多困难:我需要在 XSLT 中执行类似 while 的循环。我认为 for-each 不足以解决这个问题。

我有一个变量是 SELECT 语句的结果。它可以返回 0 或整数。如果值为0,则需要再次执行SELECT,发送另一个参数,看看值是否不同。

我只能考虑使用类似 while 的循环,但也许它有另一种实现方式?就像使用模板并最终调用自己一样?有可能吗?

类似的东西:

<!-- initiate TEMPLATE -->
<!-- WHILE $VALUE = 0 -->
<xsl:variable name="sql.query">
    <sql:param name="SQL_QUERY">SELECT $value FROM date_table WHERE date='$date'</mx:param>
</xsl:variable>

<xsl:variable name="VALUE">
    <xsl:value-of select="sql:exec-formula('generic.sql', exsl:node-set($sql.query)//sql:param)" /> <!-- this will bring the result of the SELECT in the variable -->
</xsl:variable>

<xsl:variable name="date">
    <xsl:value-of select="$date-1" /> <!-- something like that, it doesn't matter -->
</xsl:variable>

<xsl:if test="$VALUE ='0'">
    <!-- call template again -->
</xsl:if>
<!-- end of template -->

【问题讨论】:

    标签: sql xslt loops while-loop


    【解决方案1】:
    <!-- recursive named template -->
    <xsl:template name="while">
    
     <xsl:variable name="VALUE">
     <!-- your evaluation -->
     </xsl:variable>
    
     <!-- evaluate and recurse -->
     <xsl:if test="$VALUE=0">
        <xsl:call-template name="while"/>
     </xsl:if>
    
    </xsl:template>
    

    【讨论】:

    • 容易出现堆栈溢出的错误。
    【解决方案2】:

    喜欢使用模板并最终调用自己?

    正确:尾递归是该问题的常用解决方案,如 empo 所示。更好的 XSLT 处理器将优化尾递归,因此它不会占用堆栈。更糟糕的会在 500 次左右迭代后耗尽堆栈空间,在这种情况下,您需要寻找不同的解决方案。

    注意:尽量避免这种结构

    <xsl:variable name="date">
        <xsl:value-of select="$date - 1" /> 
    </xsl:variable>
    

    什么时候可以做

    <xsl:variable name="date" select="$date - 1" /> 
    

    它不必要地冗长,而且效率也很低,因为变量值是一棵树而不是简单的字符串或数字。

    【讨论】:

    • 感谢您在变量构造中的提示。我尝试了尾递归方法,它完美无缺。
    猜你喜欢
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多