web-dev-qa-db-ja.com

XSLTのfor-eachループを解除する方法

XSLTのfor-eachループを解除する方法

19
Daniel Silveira

XSLTは非常に機能的なスタイルで記述されており、このスタイルにはbreakステートメントに相当するものはありません。あなたができることは次のようなものです:

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

そのようにfor-eachは引き続きすべてのノードを反復処理しますが、ループの本体は条件がtrueの場合にのみ実行されます。

28
Greg Hewgill

for-each要素のselect属性に「ループ」を停止するための条件を入力します。たとえば、4つの要素の後に「ブレーク」するには:

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

ある特定の条件を満たすノードまで反復しますが、ノードを含めません。

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

XSLTは手続き型言語ではありません。 Javaでループを作成する場合のfor-eachを「ループ」とは考えないでください。 For-Eachは、一連のアイテムのそれぞれにテンプレートを適用する方法です。これは必ずしも特定の順序で行われるとは限らないため、「このテンプレートを一連のアイテムのそれぞれに適用し、そういったことが発生してから停止する」と考えることはできません。

つまり、select属性を使用して結果をフィルター処理できるので、「一連のアイテムのそれぞれにテンプレートを適用しますが、それらに当てはまる場合のみ」のようになります。

あなたが本当に望んでいるのは、「そのようなものはそれらに当てはまるが、これが当てはまる最初のものにのみである、一連のアイテムのそれぞれにテンプレートを適用すること」である場合、select属性を位置と組み合わせることができます() 関数。

8
Jacob Mattison

<xsl:for-each> XSLT命令の本体からの「ブレーク」は、構文構成体を使用して指定できませんが、それはシミュレートできます

Topxml.comにあるこのコードスニペットは、この手法を詳細に説明しています。

xsl:for-eachループから「 "ブレーク"」が必要な場合

基本的に2つの手法について説明します

  1. 特定の条件が満たされた場合にのみ、<xsl:for-each>の本体内で何かを実行します。

  2. <xsl:for-each>を使用せずに再帰処理を指定する

2番目の方法には、すぐに終了を実行できるという利点があります。1番目の方法は、その後も多くの「空のサイクル」を実行する必要があります。終了条件が満たされました。

4

私も同じような状況でしたが、ここに私が書いたコードがあります。論理的な理由から、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>
0
rjose

こんにちは、これは古い投稿ですが、他の開発者の役に立つかもしれません。 XSLTでfor eachを分割する方法を見つけましたが、それは文字通りの区切りではありませんが、コードを見るとそれがわかります。ご存知かどうかは不明ですが、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>
0
orophine