将xsl:template的执行限制为指定的次数

时间:2013-02-18 09:19:08

标签: xml xslt loops

这是我的XSLT:

<!-- Looping through both Items and Categories of Items -->
<xsl:for-each select="statement">

    <!-- Define whether current node is a single item or a category of items -->
    <xsl:choose>

        <!-- Category of items -->
        <xsl:when test="statement">

            <!-- Render all items in this category -->
            <xsl:for-each select="statement">
                <xsl:call-template name="renderItem" select="current()" />
            </xsl:for-each>

        </xsl:when>

        <!-- Single item -->
        <xsl:otherwise>
            <xsl:call-template name="renderItem" select="." />
        </xsl:otherwise>

    </xsl:choose>

</xsl:for-each>

我希望能够输出特定数量的项目,但不能全部输出。 如何使“renderItem”执行不超过4次?

2 个答案:

答案 0 :(得分:2)

你的代码看起来很奇怪:所有这些xsl:choose,xsl:for-each和xsl:call-template看起来像应用模板和模板规则的自制实现。此外,xsl:call-template不接受select属性 - 这是一个语法错误,你的XSLT处理器应该标记它,而不是简单地忽略它。

忽略这一点,我认为对您的问题最简单的解决方案是测试您是否要通过检查其在树中的位置来处理项目。像

这样的东西
<xsl:template match="statement">
  <xsl:variable name="pos">
    <xsl:number level="any" from="..."/>
  </xsl:variable>
  <xsl:if test="$pos &lt; 5">...
</xsl:template>

答案 1 :(得分:0)

您的问题的解决方案依赖于使用递归,手动控制模板执行的次数(或计算项目呈现的次数)。

更多的是如何实现它而不是解决问题的方法(我不知道你的XML文件是怎么样的),但是我试图调整你发布的代码(可能是错误的,没有XML我不确定。)

<xsl:template match="renderItems">
    <!-- Set of items to process -->
    <xsl:param name="items" />
    <!-- Tracks number of times that this template is going to be executed -->
    <xsl:param name="count" />

    <!-- Check if we have available executions -->
    <xsl:if test="$count > 0">
        <!-- Define whether the current node is a single item or a category of items -->
        <xsl:choose>
            <!-- Category of items -->
            <xsl:when test="$items/statement">
                <!-- Select the number of items which are going to be rendered taking into
                     account the count parameter -->
                <xsl:variable name="items-to-render"
                              select="$items/statement[position() &lt;=$count]" />
                <!-- Render item in this category -->
                <xsl:for-each select="$items-to-render">
                    <!-- 
                        Do whatever you have to do with each item
                    -->
                </xsl:for-each>
                <!-- Call this template again with the updated values -->
                <xsl:call-template name="renderItems">
                    <!-- Remove the category of items from the items to be processed -->
                    <xsl:with-param name="items"
                                    select="$items[position() > 1]" />
                    <!-- Extract from the count, the number of items that we already processed -->
                    <xsl:with-param name="count"
                                    select="$count - count($items-to-render)" />
                </xsl:call-template>
            </xsl:when>
            <!-- Single item -->
            <xsl:otherwise>
                <!-- Render this item -->
                <!--
                    Do whatever you have to do with each item
                -->
                <!-- Call this template again with the updated values -->
                <xsl:call-template name="renderItems">
                    <!-- Remove this item from the items to be processed -->
                    <xsl:with-param name="items"
                                    select="$items[position() > 1]" />
                    <!-- One item less to process -->
                    <xsl:with-param name="count"
                                    select="$count - 1" />
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>       
    </xsl:if>

</xsl:template>

然后你可以使用(或类似的东西)调用模板。

<xsl:call-template name="renderItems">
    <xsl:with-param name="items"
                    select="statement" />
</xsl:call-template>