For Each スコープ

For Each スコープは、ペイロードを要素に分割し、それらを 1 つずつ、スコープ内に配置したコンポーネントで処理します。 これは、ほとんどのプログラミング言語の ​for-each​/​for​ loop コードブロックに似ており、リストや配列を含め、あらゆるコレクションを処理できます。 コレクションには、サポートされている任意のコンテンツ種別 (​application/json​、​application/java​、​application/xml​ など) を使用できます。

For Each スコープに関する一般的な考慮事項:

  • デフォルトでは、For Each はペイロードを分割しようとします。ペイロードが単純な Java コレクションであれば、For Each スコープは設定なしでペイロードを分割できます。For Each スコープ内のペイロードは、分割された各要素です。元のメッセージ内の属性は、メッセージ全体に関連するため無視されます。

  • For Each によって、現在のペイロードは変更されません。出力ペイロードは入力と同じです。

  • XML や JSON など、Java 以外のコレクションの場合は、DataWeave 式を使用してデータを分割します。それには ​[Collection (コレクション)]​ 項目を使用します。

    次の例では、For Each の ​[Collection (コレクション)]​ 項目は、​payload.topics​ に保存された配列に対して反復処理を行うように設定されています。

    For Each コンポーネント

For Each スコープでは、各反復中にコレクションの各項目が ​payload​ に保存されます。

配列をバッチに分割することで、処理時間を短縮することもできます。各バッチは、個別の Mule メッセージとして処理されます。たとえば、コレクションに 200 個の要素があり、​[Batch Size (バッチサイズ)]​ を ​50​ に設定すると、For Each スコープは 50 個の要素から成る 4 つのバッチをそれぞれ個別の Mule メッセージとして反復処理します。

サンプル XML

これは、上述の For Each スコープ設定に基づくサンプル XML です。

...
  <foreach doc:name="For Each" collection="#[payload.topics]" batchSize="1" rootMessageVariableName="rootMessage" counterVariableName="counter">
      <file:write ... >
      <!--Any other module that you want to include in the For Each scope -->
  </foreach>
...

変数の伝播

For Each スコープの各実行は、ブロックの前回の実行からの変数と値を使用して開始されます。1 つの要素の処理時に作成された新しい変数や既存の変数に加えられた変更は、別の要素の処理中に参照できます。変数へのこれらの変更は、引き続き For Each スコープの外部で使用できます。

<set-variable variableName="var1" value="var1"/>
<set-variable variableName="var2" value="var2"/>
<foreach collection="#[['apple', 'banana', 'orange']]">
    <choice>
        <when expression="#[payload == 'apple']">
            <set-variable variableName="var2" value="newValue"/>
            <set-variable variableName="var3" value="appleVal"/>
        </when>
        <when expression="#[payload == 'banana']">
            <set-variable variableName="var3" value="#[vars.var3 ++ ' bananaVal']"/>
            <!-- var3 will now have value 'appleVal bananaVal'-->
        </when>
        <otherwise>
            <set-variable variableName="var3" value="otherVal"/>
            <set-variable variableName="var4" value="val4"/>
        </otherwise>
    </choice>
</foreach>

集約後、変数は次のようになります。

{var1: "var1", var2: "newValue", var3: "otherVal", var4: "val4"}

エラー処理

コレクション内のいずれかの要素で例外がスローされると、For Each スコープはそのコレクションの処理を停止し、エラーハンドラを呼び出します。

サンプルプロジェクト

Anypoint Exchange にはいくつかのサンプルプロジェクトがあり、Anypoint Studio でそれらを開いて For Each スコープの使用方法について詳しく学ぶことができます。

  • Authenticating Salesforce using OAuth2 (OAuth2 を使用した Salesforce の認証)

  • Import contacts into Microsoft Dynamics CRM (Microsoft Dynamics CRM への取引先責任者のインポート)

  • Importing a CSV file into mongoDB (mongoDB への CSV ファイルのインポート)

  • Importing an Email Attachment using the IMAP Connector (IMAP Connector を使用したメールの添付ファイルのインポート)

  • Importing Email Attachments using the POP3 Connector (POP3 Connector を使用したメールの添付ファイルのインポート)

  • Querying a Database and Attaching Results to an Email (データベースへのクエリ実行とメールへの結果の添付)

Anypoint Studio でサンプルプロジェクトをダウンロードして開くには、左上隅にある Exchange アイコンをクリックします。次に、開いたウィンドウで、Anypoint Exchange にログインし、プロジェクトの名前を検索します。

XML リファレンス

For Each スコープの開始と終了には ​<foreach>​ タグを使用します。このスコープの影響を受けるコンポーネントは、​<foreach>​ タグの子要素として定義されます。

設定可能なプロパティ

プロパティ Default (デフォルト) 説明

collection

payload

Java コレクション、オブジェクト配列、マップ、または DOM ノードを返す式。

counterVariableName

counter

反復処理を行うメッセージ数を保存するプロパティの名前。

batchSize

1

コレクションを指定されたサイズのサブコレクションに分割します。たとえば、コレクションに 200 個の要素があり、バッチサイズを 50 に設定すると、50 個の要素から成る 4 つのバッチを処理します。

rootMessageVariableName

rootMessage

親メッセージを保存するプロパティの名前。親は、分割されていない完全なメッセージです。

For Each スコープと Parallel For Each スコープの違い

For Each と Parallel For Each のどちらも定義済みコレクションを分割し、スコープ内のコンポーネントがコレクションの各要素を処理します。どちらの場合も、同じ初期コンテキストで各ルートが実行されます。これらの 2 つのスコープの違いは、次のとおりです。

  • For Each は順次処理で、Parallel For Each は並列処理です。 この違いは​エラー処理​に影響します。

    処理の違いのため、For Each の実行はエラーの発生時に中断されてエラーハンドラが呼び出されますが、Parallel For Each は ​MULE:COMPOSITE_ROUTE​ エラー種別でエラーハンドラを呼び出す前にすべてのルートを処理します。

  • For Each はペイロードを変更しませんが、Parallel For Each は各反復の出力メッセージのコレクションを出力します。

「並列 For Each スコープ」​を参照してください。