如何在XSLT中打破for-each循环?

时间:2022-04-15 07:39:54

How-to break a for-each loop in XSLT?

如何在XSLT中打破for-each循环?

6 个解决方案

#1


XSLT is written in a very functional style, and in this style there is no equivalent of a break statement. What you can do is something like this:

XSLT是以非常实用的方式编写的,并且在这种风格中没有相应的break语句。你能做的是这样的:

<xsl:for-each select="...nodes...">
    <xsl:if test="...some condition...">
        ...body of loop...
    </xsl:if>
</xsl:for-each>

That way the for-each will still iterate through all the nodes, but the body of the loop will only be executed if the condition is true.

这样,for-each仍将遍历所有节点,但只有条件为真时才会执行循环体。

#2


Put the condition for stopping the "loop" in the select attribute of the for-each element. For instance, to "break" after four elements:

在for-each元素的select属性中设置停止“循环”的条件。例如,要在四个要素之后“打破”:

<xsl:for-each select="nodes[position()&lt;=4]">

To iterate up to but not including a node that satisfied some particular condition:

迭代但不包括满足某些特定条件的节点:

<xsl:for-each select="preceding-sibling::node[condition]">

#3


XSLT isn't a procedural language; don't think of for-each as being a "loop" in the way you have a loop in Java. For-each is a way to apply a template to each of a bunch of items. It doesn't necessarily happen in a particular order, so you can't think of it as "apply this template to each of a bunch of items until such-and-such happens, then stop".

XSLT不是一种过程语言;不要把for-each视为你在Java中循环的方式的“循环”。 For-each是一种将模板应用于一堆项目的方法。它不一定按特定的顺序发生,所以你不能把它想象为“将这个模板应用到一堆项目中,直到发生这种情况,然后停止”。

That said, you can use the select attribute to filter the results, so it becomes more like "apply a template to each of a bunch of items, but only if such-and-such is true of them".

也就是说,您可以使用select属性来过滤结果,因此它更像是“将模板应用于每个项目中的每一个,但只有在这样的情况下才适用”。

If what you really want is "apply a template to each of a bunch of items, where such-and-such is true of them, but only to the first one this is true of", you can combine the select attribute with the position() function.

如果您真正想要的是“将模板应用于一堆项目中的每一项都是如此,但只有第一项才是真实的”,您可以将select属性与位置结合使用()函数。

#4


A "break" from the body of an <xsl:for-each> XSLT instruction cannot be specified using a syntactic construct, however it can be simulated.

不能使用语法结构指定来自 XSLT指令主体的“中断”,但可以对其进行模拟。

This code snippet at topxml.com describes the technique in detail:

topxml.com上的这段代码片段详细介绍了该技术:

In case you need a ""break"" from an xsl:for-each loop

如果您需要来自xsl:for-each循环的“break”

Essentially two techniques are discussed:

基本上讨论了两种技术:

  1. Performing something inside the body of <xsl:for-each> only if a specific condition is satisfied.

    仅在满足特定条件时才在 的主体内执行某些操作。

  2. Specifying the processing not using <xsl:for-each> but with recursion

    指定处理不使用 但使用递归

The second method has the benefit of being able to perform the exit immediately, contrasted with the first method having to still perform many "empty cycles" even after the exit-condition has been satisfied.

第二种方法具有能够立即执行退出的优点,与第一种方法相比,即使在满足退出条件之后仍必须执行许多“空循环”。

#5


Hello I kwow this is an old post but maybe it can help other developers. I have found a way to break a for each in XSLT it is not litteraly a break but if you see the code you will get it. As you know or not know you can use inline C# code in xslt. In this example i want to loop al the nodes and take the first NTE node with Value RC But if I get a node that differs from the NTE node i want to stop looking at the condition. So I set a global variable in C# code and I ask the value each time I go through a node:

您好,我知道这是一个老帖子,但也许它可以帮助其他开发人员。我已经找到了一种在XSLT中为每个打破一个方法的方法它不是一个休息但是如果你看到代码就会得到它。如您所知或不知道您可以在xslt中使用内联C#代码。在这个例子中,我想循环节点并使用值RC获取第一个NTE节点但是如果我得到一个与NTE节点不同的节点,我想停止查看条件。所以我在C#代码中设置了一个全局变量,每次通过一个节点时我都会询问这个值:

    <xsl:value-of select="userCSharp:SetStopForeach('true')" />
<xsl:for-each select="following-sibling::node()">

        <xsl:if test="local-name()='NTE_NotesAndComments_3' and userCSharp:GetStopForeach()" >

        <xsl:for-each select="NTE_4_CommentType">
            <xsl:if test="(CE_0364_0_IdentifierSt)[text()=&quot;RC&quot;]"> 
        <ns0:RESULTAAT_COMMENTAAR>
                    <xsl:for-each select="../NTE_3_Comment">

                        <xsl:value-of select="./text()" />
                    </xsl:for-each>
                </ns0:RESULTAAT_COMMENTAAR> 
            </xsl:if>
        </xsl:for-each>
        </xsl:if>
        <xsl:if test="local-name()='ORC_CommonOrder'" >
            <xsl:value-of select="userCSharp:SetStopForeach('false')" />
        </xsl:if>
    </xsl:for-each>


    .....

    <msxsl:script language="C#" implements-prefix="userCSharp">
 <![CDATA[ 

    public bool StopForeach=false;
    public bool GetStopForeach() {
        return StopForeach;
    }
    public string SetStopForeach(bool aValue) {
         StopForeach=aValue;
         return "";
    }

      ]]> 
      </msxsl:script>

#6


I had a similar situation and here is the code I had written. For logical reasons, I couldn't fit in the other conditions with condition01.

我有类似的情况,这是我写的代码。出于逻辑原因,我无法适应condition01的其他条件。

<xsl:for-each select="msxsl:node-set($DATA6)[condition01]"> 
<xsl:choose>
<xsl:when test="not((condtion02 or  condition03) and condition04)">
--body of for loop 
</xsl:when>
</xsl:choose>
</xsl:for-each>

#1


XSLT is written in a very functional style, and in this style there is no equivalent of a break statement. What you can do is something like this:

XSLT是以非常实用的方式编写的,并且在这种风格中没有相应的break语句。你能做的是这样的:

<xsl:for-each select="...nodes...">
    <xsl:if test="...some condition...">
        ...body of loop...
    </xsl:if>
</xsl:for-each>

That way the for-each will still iterate through all the nodes, but the body of the loop will only be executed if the condition is true.

这样,for-each仍将遍历所有节点,但只有条件为真时才会执行循环体。

#2


Put the condition for stopping the "loop" in the select attribute of the for-each element. For instance, to "break" after four elements:

在for-each元素的select属性中设置停止“循环”的条件。例如,要在四个要素之后“打破”:

<xsl:for-each select="nodes[position()&lt;=4]">

To iterate up to but not including a node that satisfied some particular condition:

迭代但不包括满足某些特定条件的节点:

<xsl:for-each select="preceding-sibling::node[condition]">

#3


XSLT isn't a procedural language; don't think of for-each as being a "loop" in the way you have a loop in Java. For-each is a way to apply a template to each of a bunch of items. It doesn't necessarily happen in a particular order, so you can't think of it as "apply this template to each of a bunch of items until such-and-such happens, then stop".

XSLT不是一种过程语言;不要把for-each视为你在Java中循环的方式的“循环”。 For-each是一种将模板应用于一堆项目的方法。它不一定按特定的顺序发生,所以你不能把它想象为“将这个模板应用到一堆项目中,直到发生这种情况,然后停止”。

That said, you can use the select attribute to filter the results, so it becomes more like "apply a template to each of a bunch of items, but only if such-and-such is true of them".

也就是说,您可以使用select属性来过滤结果,因此它更像是“将模板应用于每个项目中的每一个,但只有在这样的情况下才适用”。

If what you really want is "apply a template to each of a bunch of items, where such-and-such is true of them, but only to the first one this is true of", you can combine the select attribute with the position() function.

如果您真正想要的是“将模板应用于一堆项目中的每一项都是如此,但只有第一项才是真实的”,您可以将select属性与位置结合使用()函数。

#4


A "break" from the body of an <xsl:for-each> XSLT instruction cannot be specified using a syntactic construct, however it can be simulated.

不能使用语法结构指定来自 XSLT指令主体的“中断”,但可以对其进行模拟。

This code snippet at topxml.com describes the technique in detail:

topxml.com上的这段代码片段详细介绍了该技术:

In case you need a ""break"" from an xsl:for-each loop

如果您需要来自xsl:for-each循环的“break”

Essentially two techniques are discussed:

基本上讨论了两种技术:

  1. Performing something inside the body of <xsl:for-each> only if a specific condition is satisfied.

    仅在满足特定条件时才在 的主体内执行某些操作。

  2. Specifying the processing not using <xsl:for-each> but with recursion

    指定处理不使用 但使用递归

The second method has the benefit of being able to perform the exit immediately, contrasted with the first method having to still perform many "empty cycles" even after the exit-condition has been satisfied.

第二种方法具有能够立即执行退出的优点,与第一种方法相比,即使在满足退出条件之后仍必须执行许多“空循环”。

#5


Hello I kwow this is an old post but maybe it can help other developers. I have found a way to break a for each in XSLT it is not litteraly a break but if you see the code you will get it. As you know or not know you can use inline C# code in xslt. In this example i want to loop al the nodes and take the first NTE node with Value RC But if I get a node that differs from the NTE node i want to stop looking at the condition. So I set a global variable in C# code and I ask the value each time I go through a node:

您好,我知道这是一个老帖子,但也许它可以帮助其他开发人员。我已经找到了一种在XSLT中为每个打破一个方法的方法它不是一个休息但是如果你看到代码就会得到它。如您所知或不知道您可以在xslt中使用内联C#代码。在这个例子中,我想循环节点并使用值RC获取第一个NTE节点但是如果我得到一个与NTE节点不同的节点,我想停止查看条件。所以我在C#代码中设置了一个全局变量,每次通过一个节点时我都会询问这个值:

    <xsl:value-of select="userCSharp:SetStopForeach('true')" />
<xsl:for-each select="following-sibling::node()">

        <xsl:if test="local-name()='NTE_NotesAndComments_3' and userCSharp:GetStopForeach()" >

        <xsl:for-each select="NTE_4_CommentType">
            <xsl:if test="(CE_0364_0_IdentifierSt)[text()=&quot;RC&quot;]"> 
        <ns0:RESULTAAT_COMMENTAAR>
                    <xsl:for-each select="../NTE_3_Comment">

                        <xsl:value-of select="./text()" />
                    </xsl:for-each>
                </ns0:RESULTAAT_COMMENTAAR> 
            </xsl:if>
        </xsl:for-each>
        </xsl:if>
        <xsl:if test="local-name()='ORC_CommonOrder'" >
            <xsl:value-of select="userCSharp:SetStopForeach('false')" />
        </xsl:if>
    </xsl:for-each>


    .....

    <msxsl:script language="C#" implements-prefix="userCSharp">
 <![CDATA[ 

    public bool StopForeach=false;
    public bool GetStopForeach() {
        return StopForeach;
    }
    public string SetStopForeach(bool aValue) {
         StopForeach=aValue;
         return "";
    }

      ]]> 
      </msxsl:script>

#6


I had a similar situation and here is the code I had written. For logical reasons, I couldn't fit in the other conditions with condition01.

我有类似的情况,这是我写的代码。出于逻辑原因,我无法适应condition01的其他条件。

<xsl:for-each select="msxsl:node-set($DATA6)[condition01]"> 
<xsl:choose>
<xsl:when test="not((condtion02 or  condition03) and condition04)">
--body of for loop 
</xsl:when>
</xsl:choose>
</xsl:for-each>