Xslt 记住for-each循环中递归调用模板的最后计数

Xslt 记住for-each循环中递归调用模板的最后计数,xslt,xslt-1.0,Xslt,Xslt 1.0,我有一个XSLT映射,用于一些转换。我的问题是我怎么能记住计数1.e;循环已运行的次数。比如说 <xsl: for each> // This runs some 3 times <xsl: call-template > // This call template recursively runs 10 times <xsl: with- param > </xsl: call-template > <xsl: for each>

我有一个XSLT映射,用于一些转换。我的问题是我怎么能记住计数1.e;循环已运行的次数。比如说

<xsl: for each>  // This runs some 3 times

<xsl: call-template > // This call template recursively runs 10 times
<xsl: with- param >
</xsl: call-template >

<xsl: for each>
//这会运行大约3次
//此调用模板递归运行10次
在上面的示例中,外部for循环运行3次,内部调用模板重新调用自身以打印某些内容(假设10次)。所以我总共有3*10=30个循环

这里我需要的是假设我有一个初始编号001,当for循环第一次运行时,它将调用模板,该模板将递归调用自身10次。所以我打印了从001到010的数字

下一次我运行循环时,我再次打印了001-010 ans的第三次数字。但我想记住最后一次计数。假设在第一次迭代中我达到了010。所以在第二次迭代中,我将从011开始计数,并打印到021。 第三次我将从022-032开始打印

但是有人能建议我怎么做吗?我怎样才能记住打印已完成的最后一个值

还有一件事我实际上仅限于XSLT1.0。这就是我必须像上面的例子那样循环的原因

这将是一个很大的帮助

我想做的就是这样, 假设我有一个输入xml作为

<A>

<B from="123456781" to="123456782">
........
</B>
<B from="123456781" to="123456785">
........
</B>
<B from="123456788" to="123456788">
........
</B>

</A>

........
........
........
在上面的xml中,每个节点B都与范围“从到”相关联。我需要在给定范围内创建尽可能多的ouputB节点。我还必须得到创建的每个outputB节点的唯一计数。例如,输出xml可以如下所示:

<root>

<outputB value="123456781" id="001"> // from first B node from="123456781" to="123456782"
<outputB value="123456782" id="002">

<outputB value="123456781" id="003">
<outputB value="123456782" id="004">// from second B node from="123456781" to="123456785"
<outputB value="123456783" id="005">
<outputB value="123456784" id="006">
<outputB value="123456785" id="007">

<outputB value="123456788" id="008">// from third B node from="123456788" to="123456788"

</root>

//从第一个B节点from=“123456781”到=“123456782”
//从第二个B节点from=“123456781”到=“123456785”
//从第三个B节点从=“123456788”到=“123456788”
因此,在上面的xsl中,我根据from和to参数中的范围值递归填充,同时在每个输入B节点上为每个参数删除bu。从而创建outputB节点的确切数量。但这里的问题是在生成的xml中维护唯一的计数或id


谢谢:)

除非在非常特殊的情况下,否则您不会记住XSLT中的值,甚至不会在执行过程中加起来。但是,一般来说,您不需要这样做

因此,如果你有:

<xsl:for-each select="conditiona">  // This runs some 3 times
//这会运行大约3次
然后,您就有了提供计数所需的所有信息:

<xsl:value-of select="count(conditiona)"/> // this displays 3
//这将显示3

调用模板时,只需传入一个“depth”参数

 <xsl:template Name="x">
   <xsl:param name="depth">

   <xsl:call-template name="x">
     <xsl:with param name="depth" select=="depth+1" />
   </xsl:call-template>
 </xsl:template>


然后对外部循环执行类似的操作。不清楚您是如何执行此循环的,但您可以使用position()。那么你想要的数字是position()*10+深度。

这是怎么回事?您可以在上运行它(请参阅输出源)。它完全避免了for-each(在XSLT中总是最好避免)

这里有两个关键概念:

  • 在同一节点上重复模板匹配,只要其范围需要
  • 让节点启动其后续同级节点的进程,而不是让根匹配模板应用于所有B节点。通过这种方式,可以通过传递的参数来维护“您上哪儿去了?”关系。这是非正统的,但有效
  • 代码:

    <!-- root - kick things off, for each B node -->
    <xsl:template match="/">
        <xsl:apply-templates select='//B[1]' />
    </xsl:template>
    
    <!-- iteration content - B nodes -->
    <xsl:template match='B'>
    
        <!-- recursion params -->
        <xsl:param name='index' select='@from' />
        <xsl:param name='id' select='position()' />
        <xsl:param name='pos' select='position()' />
    
        <!-- output node -->
        <outputB value='{$index}' id='{$id}' />
    
        <!-- now recurse for... -->
        <xsl:choose>
    
            <!-- ...as range requires -->
            <xsl:when test='(@from and @to) and (not($index) or $index &lt; @to)'>
                <xsl:apply-templates select='.'>
                    <xsl:with-param name='index' select='$index + 1' />
                    <xsl:with-param name='id' select='$id + 1' />
                </xsl:apply-templates>
            </xsl:when>
    
            <!-- ...next B node, if there is one -->
            <xsl:when test='following-sibling::B'>
                <xsl:apply-templates select='following-sibling::B[1]'>
                    <xsl:with-param name='id' select='$id + 1' />
                </xsl:apply-templates>
            </xsl:when>
        </xsl:choose>
    
    </xsl:template>
    
    <outputBs value="123456781" id="1"/>
    <outputBs value="123456782" id="2"/>
    <outputBs value="123456783" id="3"/>
    <outputBs value="123456781" id="4"/>
    <outputBs value="123456782" id="5"/>
    <outputBs value="123456783" id="6"/>
    <outputBs value="123456784" id="7"/>
    <outputBs value="123456785" id="8"/>
    <outputBs value="123456788" id="9"/>
    
    
    
    输出:

    <!-- root - kick things off, for each B node -->
    <xsl:template match="/">
        <xsl:apply-templates select='//B[1]' />
    </xsl:template>
    
    <!-- iteration content - B nodes -->
    <xsl:template match='B'>
    
        <!-- recursion params -->
        <xsl:param name='index' select='@from' />
        <xsl:param name='id' select='position()' />
        <xsl:param name='pos' select='position()' />
    
        <!-- output node -->
        <outputB value='{$index}' id='{$id}' />
    
        <!-- now recurse for... -->
        <xsl:choose>
    
            <!-- ...as range requires -->
            <xsl:when test='(@from and @to) and (not($index) or $index &lt; @to)'>
                <xsl:apply-templates select='.'>
                    <xsl:with-param name='index' select='$index + 1' />
                    <xsl:with-param name='id' select='$id + 1' />
                </xsl:apply-templates>
            </xsl:when>
    
            <!-- ...next B node, if there is one -->
            <xsl:when test='following-sibling::B'>
                <xsl:apply-templates select='following-sibling::B[1]'>
                    <xsl:with-param name='id' select='$id + 1' />
                </xsl:apply-templates>
            </xsl:when>
        </xsl:choose>
    
    </xsl:template>
    
    <outputBs value="123456781" id="1"/>
    <outputBs value="123456782" id="2"/>
    <outputBs value="123456783" id="3"/>
    <outputBs value="123456781" id="4"/>
    <outputBs value="123456782" id="5"/>
    <outputBs value="123456783" id="6"/>
    <outputBs value="123456784" id="7"/>
    <outputBs value="123456785" id="8"/>
    <outputBs value="123456788" id="9"/>
    
    
    
    XSLT是一种函数式语言。你不能用函数式语言“记住”事物:没有时间概念,没有对过去事物的记忆。您需要将输出中的所有内容作为输入中某些内容的函数进行计算。

    XSLT是一种声明性编译语言,因此不支持变量的累积赋值或覆盖,因此您无法在所描述的全局变量中跟踪这一点。你到底想达到什么目的?你能发布一些XML和所需的输出吗?@Utkanos:-我已经更新了帖子并添加了输入和输出XML,以便更好地了解我需要实现的内容。:-我已经用输入和输出XML更新了帖子。这可能会帮助你更好地理解我需要实现的目标。