Как нарушить цикл для каждого в XSLT? - PullRequest
19 голосов
/ 22 января 2009

Как разорвать цикл для каждого в XSLT?

Ответы [ 6 ]

28 голосов
/ 22 января 2009

XSLT написан в очень функциональном стиле, и в этом стиле нет эквивалента оператора break. Что вы можете сделать, это что-то вроде этого:

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

Таким образом, for-each все еще будет повторяться по всем узлам, но тело цикла будет выполнено только в том случае, если условие истинно.

17 голосов
/ 14 декабря 2011

Поместите условие остановки цикла в атрибут select элемента for-each. Например, «разбить» после четырех элементов:

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

Для итерации до, но не включая узел, который удовлетворял определенному условию:

<xsl:for-each select="preceding-sibling::node[condition]">
8 голосов
/ 22 января 2009

XSLT не является процедурным языком; не думайте о for-each как о «цикле» в том, как у вас есть цикл в Java. For-each - это способ применить шаблон к каждому из множества элементов. Это не обязательно происходит в определенном порядке, поэтому вы не можете думать о нем как о том, что «примените этот шаблон к каждому из множества элементов, пока не произойдет то-то и то-то, а затем остановитесь».

Тем не менее, вы можете использовать атрибут select для фильтрации результатов, так что это больше похоже на "применить шаблон к каждому из набора элементов, но только если такое-то верно для них".

Если вы действительно хотите «применить шаблон к каждому из набора элементов, где то-то и то-то верно для них, но только к первому, к которому это относится», вы можете объединить атрибут select с функцией position ().

4 голосов
/ 23 января 2009

«Отрыв» от тела инструкции <xsl:for-each> XSLT не может быть указан с использованием синтаксической конструкции , однако его можно смоделировать .

Этот фрагмент кода на topxml.com описывает технику подробно:

В случае, если вам нужен "" разрыв "из цикла xsl: for-each

Обсуждаются, по сути, две техники :

  1. Выполнение чего-либо внутри тела <xsl:for-each> только при соблюдении определенного условия.

  2. Задание обработки не с использованием <xsl:for-each>, а с рекурсией

Преимущество второго метода заключается в возможности немедленного выполнения выхода , в отличие от первого метода, который по-прежнему должен выполнять много "пустых циклов" даже после того, как условие выхода выполнено.

0 голосов
/ 23 июня 2017

У меня была похожая ситуация, и вот код, который я написал. По логическим причинам я не смог вписаться в другие условия с условием 01.

<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>
0 голосов
/ 04 марта 2013

Здравствуйте, я знаю, что это старый пост, но, возможно, он может помочь другим разработчикам. Я нашел способ разбить для каждого в XSLT, это не просто перерыв, но если вы увидите код, вы получите его. Как вы знаете или не знаете, вы можете использовать встроенный код C # в xslt. В этом примере я хочу зациклить все узлы и взять первый узел NTE со значением RC. Но если я получу узел, который отличается от узла 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...