For Each (<foreach/>)

logo cloud IDE Cloud IDE

logo desktop IDE Desktop IDE

他のプログラミング言語の ​for-each​ または ​for​ ループに似たパターンで入力を処理します。

コンポーネント XML

このコンポーネントは、次の XML 構造をサポートします。

<foreach doc:name="For Each"
  doc:id="119e4859"
  collection="#[payload]"
  counterVariableName="counter"
  batchSize="1"
  rootMessageVariableName="rootMessage" />

For Each (​<foreach/>​) 属性は UI および XML で設定できます。

属性名 属性 XML 説明

Foreach​ (デフォルト)

doc:name

キャンバスに表示されるコンポーネントの編集可能な名前。

なし

doc:id

コンポーネントの自動生成された識別子。

Collection (コレクション)

collection

Java コレクション、オブジェクト、配列、マップ、または DOM ノードを返す DataWeave 式。For Each は、コレクションを要素 (オブジェクトの JSON 配列内の最上位レベルのオブジェクトなど) に自動的に分割します。各要素は、For Each 内のプロセッサーが処理する ​payload​ になります。For Each は、サポートされている任意のコンテンツタイプ (​application/json​、​application/java​、​application/xml​ など) のコレクションを受け入れます。デフォルトは ​payload​ です。

Batch size (バッチサイズ)

batchSize

入力から収集された要素を指定されたサイズのサブコレクションに分割するためにスコープが使用する数値。たとえば、For Each への入力が 199 要素の配列で、バッチサイズを 50 に設定した場合、スコープはそれぞれ 50 要素の配列を 3 つと、49 要素の配列を 1 つ生成します。デフォルトは ​1​ です。

Root message variable name (ルートメッセージ変数名)

rootMessageVariableName

元の入力からの分割されていない完全な Mule メッセージを For Each に格納する変数の設定可能な名前。メッセージにはペイロードと属性が含まれますが、Mule メッセージを含む Mule イベントの一部である変数 (​vars​) は含まれません。For Each 内では、​vars.rootMessage.payload​ を使用してメッセージのペイロードの値にアクセスし、​vars.rootMessage.attributes​ を使用してメッセージの属性にアクセスできます。For Each はこの変数をコンシュームするため、この変数にはスコープ内からのみアクセスできます。For Each 外部では、変数は ​null​ を返します。デフォルトは ​rootMessage​ です。

Counter variable name (カウンター変数名)

counterVariableName

特定の要素の各反復に番号を割り当てる変数の名前。シーケンスは ​1​ から順番に進みます。このプロパティのデフォルト名 (​counter​) を使用すると、​vars.counter​ でこの数値にアクセスできます。For Each はこの変数をコンシュームするため、スコープ外部で使用することはできず、​null​ を返します。デフォルトは ​counter​ です。

次の例では、受け取ったオブジェクトの配列を収集し、個別のオブジェクトに分割します。スコープ内のコンポーネントは、各オブジェクトの一部を選択し、その選択されたコンテンツの一部を個別のファイルに書き込み、For Each 内で結果として生じる新しい ​payload​ をログに記録します。

For Each は、この オブジェクトの JSON 配列​に対するスケジュール済み HTTP 要求から入力を受け取るとします。

(1)
<foreach doc:name="For Each" collection="#[payload]">
  (2)
  <ee:transform doc:name="Transform Message" >
    <ee:message >
      <ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload.company]]></ee:set-payload>
    </ee:message>
  </ee:transform>
  (3)
  <file:write doc:name="Write"
    path='#[(payload.name replace " " with("-") ++ "-") ++ (now() as String {format: "uuuuMMddHHmmss"}) ++ ".json"]'
    config-ref="File_Config" mode="CREATE_NEW"/>
  (4)
  <logger level="INFO" doc:name="Logger" message="#[payload]"/>
</foreach>

For Each は入力配列を処理します。

1 For Each (​<foreach />​) は入力ペイロード全体を収集し、その中の次のような 10 個の最上位 JSON オブジェクトに分割します。
{
  "id": 1,
  "name": "Leanne Graham",
  "username": "Bret",
  "email": "Sincere@april.biz",
  "address": {
    "street": "Kulas Light",
    "suite": "Apt. 556",
    "city": "Gwenborough",
    "zipcode": "92998-3874",
    "geo": {
      "lat": "-37.3159",
      "lng": "81.1496"
    }
  },
  "phone": "1-770-736-8031 x56442",
  "website": "hildegard.org",
  "company": {
    "name": "Romaguera-Crona",
    "catchPhrase": "Multi-layered client-server neural-net",
    "bs": "harness real-time e-markets"
  }
}
2 For Each は各オブジェクトを反復処理するため、Transform コンポーネント (​<ee:transform />​) の DataWeave 式 (​payload.company​) は DataWeave セレクターを使用して各 ​"company"​ キーの値を抽出し、​payload​ をそれらのキーのそれぞれの値に変換します。Mule フローと同様に、For Each 内の次のコンポーネントは、変換されたペイロードを入力として受け取ります。
3 File Write 操作 (​<file:write />​) は、より大きな DataWeave 式内で ​payload.name​ を使用して、変換されたオブジェクトから各会社の ​name​ を選択します。各ファイルの名前は、式で指定されたパターンに従い、抽出された会社名がハイフンで区切られ、ファイル名を一意にするために日時スタンプが追加されます。たとえば、Romaguera-Crona データのファイルの名前は次のようになります。
Romaguera-Crona-20221007113314.json

デフォルトでは、この操作では、Transform Message から受信したペイロードも各ファイルに読み込まれます。

4 ログには、入力配列の最初のオブジェクトに関する次のメッセージが出力されます。
{
  "name": "Romaguera-Crona",
  "catchPhrase": "Multi-layered client-server neural-net",
  "bs": "harness real-time e-markets"
}

Mule 変数を処理する場合、For Each 内の実行は前回の実行からの Mule 変数の値で始まります。1 つの要素の処理時に作成された新しい Mule 変数または既存の変数への変更は、他の要素の処理中にアクセスできます。Mule 変数への変更は、引き続き For Each スコープの外部で使用できます。

<set-variable variableName="var1" value="var1-BeforeForEach"/>
<set-variable variableName="var2" value="var2-BeforeForEach"/>
<foreach collection="#[['apple', 'banana', 'orange']]">
    <choice>
        <when expression="#[payload == 'apple']">
            <set-variable variableName="var2" value="var2-newValue"/>
            <set-variable variableName="var3" value="var3-appleVal"/>
        </when>
        <when expression="#[payload == 'banana']">
            <set-variable variableName="var3" value="#[vars.var3 ++ ' bananaVal']"/>
            <!-- var3 will now have value 'var3-appleVal bananaVal'-->
        </when>
        <otherwise>
            <set-variable variableName="var3" value="var3-otherVal"/>
            <set-variable variableName="var4" value="var4-val4"/>
        </otherwise>
    </choice>
    <logger level="INFO" doc:name="Logger After Choice"
            message='#[ [vars.var1, vars.var2, vars.var3, vars.var4] as Array ]'/>
</foreach>
<logger level="INFO" doc:name="Logger After For Each"
         message='#[[vars.var1, vars.var2, vars.var3, vars.var4] as Array]'/>

Choice ルーター (​<choice />​) が各条件内でプロセッサーを実行すると、Logger (​Logger After Choice​) は次の変数値を出力します。

// Condition: when payload == 'apple'
.LoggerMessageProcessor:
[var1-BeforeForEach, var2-newValue, var3-appleVal, null]

// Condition: when payload == 'banana'
.LoggerMessageProcessor:
[var1-BeforeForEach, var2-newValue, var3-appleVal bananaVal, null]

// Condition: otherwise
.LoggerMessageProcessor:
[var1-BeforeForEach, var2-newValue, var3-otherVal, var4-val4]

最後の値は For Each 外部に伝播されます。Logger (​Logger After For Each​) は、最後の Choice の条件 (​otherwise​) の後に出力される値と同じ値を出力します。

[var1-BeforeForEach, var2-newValue, var3-otherVal, var4-val4]