DataWeave の演算子

DataWeave バージョン 2 では、数学演算子、等価演算子、さらに prepend、append、update などの演算子など、いくつかの演算子をサポートしています。 開始する前に、DataWeave バージョン 2 は Mule 4 アプリケーションを対象とすることに注意してください。Mule 3 アプリケーションの場合、Mule 3.9 ドキュメントの​「DataWeave の演算子」​を参照してください。他の Mule バージョンの場合は、Mule Runtime の目次のバージョンセレクターを使用できます。

数学演算子

DataWeave バージョン 2 は、ほとんどの一般的な数学演算子をサポートしています。

演算子 説明

+

加算。

-

減算。

*

乗算。

/

除算。

(-)​ および ​(+)​ 演算子では、数値の操作に加えて、配列、オブジェクト、日付など、複雑なデータ構造も操作できます。

次の例では、さまざまなデータ型で数学演算子を使用します。

ソース
%dw 2.0
output application/json
---
{ "mathOperators" : [
    { "2 + 2" : (2 + 2) },
    { "2 - 2" : (2 - 2) },
    { "2 * 2" : (2 * 2) },
    { "2 / 2" : (2 / 2) },
    { "[1,2,3] - 1 + 4" : [1,2,3] - 1 + 4},
    { "{a:1, b:2, c:3} - 'a' " : {a:1, b:2, c:3} - "a"},
    { "|2021-03-02T10:39:59| - |P1D| + |PT3H|" : |2021-03-02T10:39:59| - |P1D| + |PT3H|}
  ]
}
出力
{
  "mathOperators": [
    { "2 + 2": 4 },
    { "2 - 2": 0 },
    { "2 * 2": 4 },
    { "2 / 2": 1 },
    { "[1,2,3] - 1 + 4": [2,3,4] },
    { "{a:1, b:2, c:3} - 'a' ": {"b": 2, "c": 3} },
    { "|2021-03-02T10:39:59| - |P1D| + |PT3H|": "2021-03-01T13:39:59" }]
}

いくつかの DataWeave 関数は数値を操作します。たとえば、​sum​、​mod​ (剰余)、​avg​ (平均) などがあります。

等価演算子と比較演算子

DataWeave バージョン 2 は、次の等価演算子と比較演算子をサポートしています。

演算子 説明

<

次の値より小さい。

>

次の値より大きい。

<=

次の値以下。

>=

次の値以上。

==

次の値と等しい。

~=

値の型が異なる場合、等価演算子は、1 つの値をもう 1 つの値の型に強制変換しようとします。

論理演算子​ ​not​ を使用することで、これらの演算子を否定することができます。

次の例では、比較演算子を使用します。

ソース
%dw 2.0
output application/json
---
{ "relational" : [
    { "1 < 1" : (1 < 1) },
    { "1 > 2" : (1 > 2) },
    { "1 <= 1" : (1 <= 1) },
    { "1 >= 1" : (1 >= 1) }
  ]
}
出力
{ "relational": [
    { "(1 < 1)": false },
    { "(1 > 2)": false },
    { "(1 <= 1)": true },
    { "(1 >= 1)": true }
  ]
}

比較演算子のオペランドの型が異なる場合は、DataWeave は右側のオペランドを左側のオペランドの方に強制変換します。 たとえば、式 ​"123" > 12​ では、​12​ (数値型) が ​"12"​ (文字列型) に強制変換され、各文字列値が辞書的順序で比較されます。 式 ​123 > "12"​ では、文字列値 ​"12"​ が数値 ​12​ に強制変換され、数値が比較されます。

次の例では、等価演算子を使用しています。

ソース
%dw 2.0
output application/dw
---
{ "equality" :
  [
    (1 == 1),
    (1 == 2),
    ("true" == true),
    ("true" ~= true),
    (['true'] ~= [true]),
    ('1' ~= 1)
  ]
}
出力
{
  equality: [ true, false, false, true, true, true ]
}

論理演算子

DataWeave バージョン 2 は、次の論理演算子をサポートしています。

演算子 説明

not

入力の結果を否定します。​!​ も参照してください。

!

入力の結果を否定します。​not​ も参照してください。​DataWeave 2.2.0 で導入されました。Mule 4.2 以降でサポートされます。

and

すべての入力の結果が true の場合は ​true​ を返し、それ以外の場合は ​false​ を返します。

or

いずれかの入力の結果が true の場合は ​true​ を返し、それ以外の場合は ​false​ を返します。

not​ と ​!​ のセマンティクスは同じですが、優先順位は異なります。​not true or true​ は ​not (true or true)​ として実行されるため ​false​ を返しますが、​!true or true​ は ​true​ を返します。​!​ が最初の ​true​ にのみ適用されるためです。​!(true or true)​ は ​false​ を返します。

次の例では、論理演算子を使用します。

ソース
%dw 2.0
var myArray = [1,2,3,4,5]
var myMap = myArray map not (($ mod 2) == 0)
output application/json
---
{
  "not" : [
    "notTrue" : not true,
    "notFalse" : not false,
    "myMapWithNot" : myMap
  ],
  "and" : [
    "andTrueFalse" : true and false,
    "andIsTrue" : (1 + 1 == 2) and (2 + 2 == 4),
    "andIsFalse" : (1 + 1 == 2) and (2 + 2 == 2)
  ],
  "or" : [
    "orTrueFalse" : true or false,
    "orIsTrue" : (1 + 1 == 2) or (2 + 2 == 2),
    "orIsFalse" : (1 + 1 == 1) or (2 + 2 == 2)
  ],
  "!-vs-not" : [
	  "example-!" : (! true or true),
	  "example-not" : (not true or true)
  ]
}

myMap​ はリスト (​myArray​) 内の項目を反復処理し、剰余 (​mod​) 式が各項目に適用されたときに ​0​ と評価​されない​かどうかを決定します。

出力
{
  "not": [
    { "notTrue": false },
    { "notFalse": true },
    { "myMapWithNot": [ true, false, true, false, true ] }
  ],
  "and": [
    { "andTrueFalse": false },
    { "andIsTrue": true },
    { "andIsFalse": false }
  ],
  "or": [
    { "orTrueFalse": true },
    { "orIsTrue": true },
    { "orIsFalse": false }
  ],
  "!-vs-not": [
    { "example-!": true },
    { "example-not": false }
  ]
}

not​ は ​not (true)​ のような式では機能しますが、​not(true)​ (スペースなし) では機能しないことに注意してください。

論理演算子は組み合わせて使用することができます。次の例では、以下を使用します。

  • orNot​ 式で定義されている ​or not​。

  • andNot​ の ​and not​。

  • notWithAndNot​ の ​not​ および ​and not​。

%dw 2.0
var orNot = if (1 + 1 == 4 or not 1 == 2) {"answer": "orNot - Condition met"}
             else {"answer": "nope"}
var andNot = if (1 + 1 == 2 and not 1 == 2) {"answer": "andNot - Condition met"}
             else {"answer": "nope"}
var notWithAndNot = if (not (1 + 1 == 2 and not 1 == 1)) {"answer": "notWithAndNot - Condition met"}
              else {"answer": "nope"}
output application/json
---
{ "answers" :
  [
    orNot,
    andNot,
    notWithAndNot
  ]
}
出力
{
  "answers": [
    { "answer": "orNot - Condition met" },
    { "answer": "andNot - Condition met" },
    { "answer": "notWithAndNot - Condition met" }
  ]
}

例のすべての条件式が ​true​ に評価されるため、DataWeave は各 ​if​ ブロック内のコードを実行します。

配列用の先頭追加演算子、追加演算子、および削除加演算子

DataWeave バージョン 2 は、配列内に項目を追加および先頭に追加する演算子をサポートしています。

演算子 説明

>>

演算子の左側のデータを右側の配列内の項目の先頭に追加します。たとえば、​1 >> [2]​ の結果は ​[ 1, 2 ]​ となり、配列内の ​2​ の前に ​1​ が追加されます。

<<

演算子の右側のデータを左側の配列内の項目に追加します。たとえば、​[1] << 2​ の結果は ​[ 1, 2 ]​ となり、配列内の ​1​ の後に ​2​ が追加されます。

+

演算子の右側のデータを左側の配列内の項目に追加します。たとえば、​[1] + 2​ の結果は ​[ 1, 2 ]​ となり、配列内の ​1​ の後に ​2​ が追加されます。配列は、常に演算子の左側になります。

-

配列から、サポートされる型の指定された要素を削除します。

次の例では、配列での prepend、append、remove 演算子の使用を示します。

%dw 2.0
output application/json
---
{
  "prepend-append" : [
  	 // Array on right side when prepending.
     { "prepend" : 1 >> [2] },
     { "prepend-number" : 1 >> [1] },
     { "prepend-string" : "a" >> [1] },
     { "prepend-object" : { "a" : "b"} >> [1] },
     { "prepend-array" : [1] >> [2, 3] },
     { "prepend-binary" : (1 as Binary) >> [1] },
     { "prepend-date-time" : |23:57:59Z| >> [ |2017-10-01| ] },
  	 // Array is on left side when appending.
     { "append-number" : [1] << 2 },
     { "append-string" : [1] << "a" },
     { "append-object" : [1] << { "a" : "b"} },
     { "append-array" : [1,2] << [1, 2, 3] },
     { "append-binary" : [1] << (1 as Binary) },
     { "append-date-time" : [ |2017-10-01| ] << |23:57:59Z| },
     { "append-object-to-array" : [1,2] << {"a" : "b"} },
     { "append-array-to-array1" : ["a","b"] << ["c","d"] },
     { "append-array-to-array2" : [["a","b"],["c","d"]] << ["e","f"] },
     // + always appends within the array
     { "append-with-+" : [1] + 2 },
     { "append-with-+" : [2] + 1 },
     { "removeNumberFromArray" : ( [1,2,3] - 2 ) },
     { "removeObjectFromArray" : ( [ {a : "b"}, {c : "d"} , { e : "f"} ] - { c : "d"} ) }
  ]
}
出力
{
  "prepend-append": [
    { "prepend": [ 1, 2 ] },
    { "prepend-number": [ 1, 1 ] },
    { "prepend-string": [ "a", 1 ] },
    { "prepend-array": [ [ 1 ], 2, 3 ] },
    { "prepend-object": [ { "a": "b" }, 1 ] },
    { "prepend-binary": [ "\u0001", 1 ] },
    { "prepend-date-time": [ "23:57:59Z", "2017-10-01" ] },
    { "append-number": [ 1, 2 ] },
    { "append-string": [ 1, "a" ] },
    { "append-object": [ 1, { "a": "b" } ] },
    { "append-array": [ 1, 2, [ 1, 2, 3 ] ] },
    { "append-binary": [ 1, "\u0001" ] },
    { "append-date-time": [ "2017-10-01", "23:57:59Z" ] },
    { "append-object-to-array": [ 1, 2, { "a": "b" } ] },
    { "append-array-to-array1": [ "a", "b", ["c","d"] ] },
    { "append-array-to-array2": [ ["a","b"], ["c","d"], ["e","f"] ] },
    { "append-with-+": [ 1, 2] },
    { "append-with-+": [ 2, 1] },
    { "removeNumberFromArray": [ 1, 3 ] },
    { "removeObjectFromArray": [ { "a": "b" }, { "e": "f" } ] }
  ]
}

スコープ演算子とフローコントロール演算子

DataWeave バージョン 2 は、式のフローとスコープを制御する演算子をサポートしています。

Table 1. スコープ変数
演算子 説明

do

スコープを作成します。このスコープ内で、新しい変数、関数、アノテーション、または名前空間を宣言し、使用できます。構文は、​---​ で区切られたヘッダーと本文で構成されるという点でマッピングに似ています。このヘッダーはすべての宣言を定義する場所であり、本文は式の結果です。例については​「do」​と​「例: ローカル DataWeave 変数」​を参照してください。

using

do​ に置き換えられました。後方互換性のためにのみサポートされています。

Table 2. フローコントロール演算子
演算子 説明

if else

if​ 演算子は条件式を評価し、条件式が true の場合のみ、​if​ の下の値を返します。それ以外の場合、​else​ の下の式を返します。各 ​if​ 式に、対応する ​else​ 式が必要です。例については​「if else」​を参照してください。

else if

else if​ を組み込むと、​else​ 演算子によって if-else 構造内での式をまとめてチェーニングできます。例については​「else if」​を参照してください。

update 演算子

DataWeave では ​update​ 演算子をサポートしています。これにより、データ構造の指定された項目を新しい値で更新できます。

DataWeave 2.3.0 で導入されました。Mule 4.3 以降でサポートされます。

Mule 4.3 より前のバージョンでは、次の構文を使用して、オブジェクト全体を再作成せずに ​myInput​ の ​age​ 値を 1 ずつ増やす必要があります。

%dw 2.0
var myInput = {
    "name": "Ken",
    "lastName":"Shokida",
    "age": 30
}
output application/json
---
myInput mapObject ((value,key) ->
    if(key as String == "age")
       {(key): value as Number + 1}
    else
       {(key): value} )

Mule 4.3 では、​update​ 演算子によって構文が簡略化されています。

%dw 2.0
var myInput = {
    "name": "Ken",
    "lastName":"Shokida",
    "age": 30
}
output application/json
---
myInput update {
    case age at .age -> age + 1
}

どちらの DataWeave スクリプトでも同じ結果が返されます。

{
  "name": "Ken",
  "lastName": "Shokida",
  "age": 31
}

update​ を使用した場合、すべてのキー-値のペアでのキャストまたは反復処理は必要ありません。

update​ 構文は次のようになります。

<value_to_update> update {
    case <variable_name> at <update_expression>[!]? [if(<conditional_expression>)]? -> <new value>
    ...
}
  • value_to_update​ は更新する元の値を表します。

  • update_expression​ は ​value_to_update​ の値に一致するセレクター式です。

  • variable_name​ は一致した ​update_expression​ 値にバインドする変数の名前です。

  • new_value​ は新しい値を使用する式です。

  • [if(<conditional_expression>)]?​ ​conditional_expression​ で ​true​ が返される場合、スクリプトで値が更新されます。条件式の使用は任意です。

  • [!]​ はセレクターを upsert としてマークします。式で一致が見つからなかった場合、​!​ によって ​update​ 演算子ですべての必須要素が作成され、新しい値が挿入されます。

  • update_expression​ では複数の ​case​ 式をサポートしています。

update​ 演算子では既存の値は変換されません。代わりに、更新された式を使用して新しい値が作成されます。

セレクター式

update​ 演算子と一緒にセレクター式を使用して、更新する項目を指定します。

値セレクター

この一致セレクターでは、オブジェクト内の任意の値への一致を確認できます。

次の例では、値セレクターを使用してルートレベルの項目とネストレベルの項目を更新します。

ソース
%dw 2.0
var myInput = {
    "name": "Ken",
    "lastName":"Shokida",
    "age": 30,
    "address": {
        "street": "Amenabar",
        "zipCode": "AB1234"
    }
}
output application/json
---
myInput update {
    case age at .age -> age + 1
    case s at .address.street -> "First Street"
}
出力
{
  "name": "Ken",
  "lastName": "Shokida",
  "age": 31,
  "address": {
    "street": "First Street",
    "zipCode": "AB1234"
  }
}

インデックスセレクター

この一致セレクターを使用すれば、配列をそのインデックスで照合できます。

次の例では、配列の最初の場所にある要素を更新します。

入力
{
    "name": "Ken",
    "lastName":"Shokida",
    "age": 30,
    "addresses": [{
        "street": "Amenabar",
        "zipCode": "AB1234"
    }]
}
ソース
%dw 2.0
output application/json
---
payload update {
    case s at .addresses[0] -> {
        "street": "Second Street",
        "zipCode": "ZZ123"
    }
}
出力
{
  "name": "Ken",
  "lastName": "Shokida",
  "age": 30,
  "addresses": [
    {
      "street": "Second Street",
      "zipCode": "ZZ123"
    }
  ]
}

属性セレクター

この一致セレクターを使用すれば、属性値を照合できます。

次の例では、属性値を更新して大文字に変更します。

入力
<user name="leandro"/>
ソース
%dw 2.0
output application/json
---
payload update {
    case name at .user.@name -> upper(name)
}
出力
<?xml version='1.0' encoding='UTF-8'?>
<user name="LEANDRO"/>

動的セレクター

任意のセレクターに式を組み込み、選択を動的にできます。

次の例では、ハードコード化されていない項目の値を動的に選択して更新します。このような項目は実行時に変更される場合があります。この例では ​theFieldName​ 変数を使用してキーが ​name​ の項目を取得し、その項目の値を ​Shoki​ に変更します。

入力
{
    "name": "Ken",
    "lastName":"Shokida"
}
ソース
%dw 2.0
var theFieldName = "name"
output application/json
---
payload update {
    case s at ."$(theFieldName)" -> "Shoki"
}
出力
{
  "name": "Shoki",
  "lastName": "Shokida"
}

条件付き更新

update​ 演算子には、特定の条件で項目を変更する場合の条件付き更新を記述する構文があります。

次の例では、ユーザーの名前に基づいてカテゴリを更新します。

入力
[{"name": "Ken", "age": 30}, {"name": "Tomo", "age": 70}, {"name": "Kajika", "age": 10}]
ソース
%dw 2.0
output application/json
---
payload map ((user) ->
    user update {
        case name at .name if(name == "Ken") -> name ++ " (Leandro)"
        case name at .name if(name == "Tomo") -> name ++ " (Christian)"
    }
)
出力
[
  {
    "name": "Ken (Leandro)",
    "age": 30
  },
  {
    "name": "Tomo (Christian)",
    "age": 70
  },
  {
    "name": "Kajika",
    "age": 10
  }
]

更新/挿入

update​ 演算子を使用すれば、セレクター式の末尾にある ​!​ 記号を使用して、項目が存在しない場合に挿入できます。項目が存在しない場合、演算子によって ​null​ 値が変数にバインドされます。

次の例では、配列 ​myInput​ の各オブジェクトを更新します。項目 ​name​ がオブジェクトに存在する場合、例では ​upper​ 関数を ​name​ の値に適用します。項目 ​name​ がオブジェクトに存在しない場合、例ではキー-値のペア ​"name": "JOHN"​ をオブジェクトに追加します。

ソース
%dw 2.0
var myInput = [{"lastName": "Doe"}, {"lastName": "Parker", "name": "Peter" }]
output application/json
---
myInput  map ((value) ->
    value update {
        case name at .name! -> if(name == null) "JOHN" else upper(name)
    }
)
出力
[
  {
    "lastName": "Doe",
    "name": "JOHN"
  },
  {
    "lastName": "Parker",
    "name": "PETER"
  }
]

糖衣構文

update​ 演算子では、もっと長い ​<variable_name> at​ 構文の場所で ​$​ という名前のデフォルトの変数を受け入れます。

次の例では、式 ​.age​ の値をデフォルトの変数名 ​$​ にバインドしており、これが新しい値を表すために使用されます。もっと長い代替の構文はコメント内で示しています。

入力
{
    "name": "Ken",
    "lastName":"Shokida",
    "age": 30,
    "address": {
        "street": "Amenabar",
        "zipCode": "AB1234"
    }
}
ソース
%dw 2.0
output application/json
---
payload update {
    //equivalent expression:
    //case age at .age -> age + 1
    case .age -> $ + 1
    case .address.street -> "First Street"
}
出力
{
  "name": "Ken",
  "lastName": "Shokida",
  "age": 31,
  "address": {
    "street": "First Street",
    "zipCode": "AB1234"
  }
}