4 JSONPath機能

概要

このセクションでは、アイテムの値の前処理ステップでサポートされているJSONPathの機能について説明します。

JSONPathは、ドットで区切られたセグメントで構成されます。 セグメントは、JSON値の名前を表す単純な単語、ワイルドカード文字(*)、または角括弧で囲まれたより複雑な構文の形式を取ることができます。 角括弧で囲まれたセグメントの前のドットは省略可能であり、省略できます。

JSONPathの例 説明
$.object.name object.name の内容を返します。
$.object['name'] object.name の内容を返します。
$.object.['name'] object.name の内容を返します。
$["object"]['name'] object.name の内容を返します。
$.['object'].["name"] object.name の内容を返します。
$.object.history.length() object.history 配列要素の数を返します。
$[?(@.name == 'Object')].price.first() 名前が "Object" の最初のオブジェクトから price プロパティの値を返します。
$[?(@.name == 'Object')].history.first().length() 名前が "Object" の最初のオブジェクトから history 配列要素の数を返します。
$[?(@.price > 10)].length() 価格が10より大きいオブジェクトの数を返します。

参照: LLDマクロ値の特殊文字をJSONPathでエスケープする

サポートされているセグメント

Segment Description
<name> 名前でオブジェクトのプロパティに一致します。
* すべてのオブジェクトプロパティに一致します。
['<name>'] 名前でオブジェクトのプロパティに一致します。
['<name>', '<name>', ...] 列挙された名前のいずれかでオブジェクトのプロパティに一致します。
[<index>] インデックスで配列要素に一致します。
[<number>, <number>, ...] 列挙されたインデックスのいずれかで配列要素に一致します。
[*] すべてのオブジェクトプロパティまたは配列要素に一致します。
[<start>:<end>] 定義された範囲で配列要素に一致します:
<start> - 一致対象の最初のインデックス(含む)。指定しない場合は先頭からすべての配列要素に一致します。負の値の場合は、配列の末尾からの開始オフセットを指定します。
<end> - 一致対象の最後のインデックス(含まない)。指定しない場合は末尾まですべての配列要素に一致します。負の値の場合は、配列の末尾からの開始オフセットを指定します。
[?(<expression>)] フィルター式を適用してオブジェクト/配列要素に一致します。

一致するセグメントをその祖先を無視して検索するには(detached segment)、先頭に 2 つのドット(..)を付ける必要があります。 例えば、$..name または $..['name'] は、すべての name プロパティの値を返します。

一致した要素名は、JSONPath にチルダ(~)接尾辞を追加することで抽出できます。 これにより、一致したオブジェクトの名前、または一致した配列アイテムのインデックスが文字列形式で返されます。 出力形式は他の JSONPath クエリと同じルールに従います。確定パスの結果はそのまま返され、不確定パスの結果は配列で返されます。 ただし、確定パスに一致する要素の名前を抽出することにはほとんど意味がありません。なぜなら、その名前はすでに分かっているためです。

フィルター式

フィルター式は、中置記法による算術式です。

サポートされるオペランド:

Operand Description
"<text>"
'<text>'
テキスト定数。

例:
'value: \\'1\\''
"value: '1'"
<number> 科学的記数法をサポートする数値定数。

例: 123
<jsonpath starting with $> 入力ドキュメントのルートノードからのJSONPathで参照される値。確定パスのみサポートされます。

例: $.object.name
<jsonpath starting with @> 現在のオブジェクト/要素からのJSONPathで参照される値。確定パスのみサポートされます。

例: @.name

サポートされる演算子:

Operator Type Description Result
- Binary 減算 数値
+ Binary 加算 数値
/ Binary 除算 数値
* Binary 乗算 数値
== Binary 等価 ブール値 (1/0)
!= Binary 不等価 ブール値 (1/0)
< Binary より小さい ブール値 (1/0)
<= Binary 以下 ブール値 (1/0)
> Binary より大きい ブール値 (1/0)
>= Binary 以上 ブール値 (1/0)
=~ Binary 正規表現に一致 ブール値 (1/0)
! Unary ブールNOT ブール値 (1/0)
|| Binary ブールOR ブール値 (1/0)
&& Binary ブールAND ブール値 (1/0)

関数

関数はJSONPathの末尾で使用できます。 先行する関数が後続の関数で受け入れられる値を返す場合、複数の関数を連結できます。

サポートされている関数:

関数 説明 入力 出力
avg 入力配列内の数値の平均値 数値の配列 数値
min 入力配列内の数値の最小値 数値の配列 数値
max 入力配列内の数値の最大値 数値の配列 数値
sum 入力配列内の数値の合計 数値の配列 数値
length 入力配列内の要素数 配列 数値
first 配列の最初の要素 配列 入力配列の内容に応じたJSON構造(オブジェクト、配列、値)

JSONPathの集約関数は、引用符で囲まれた数値を受け入れます。 これらの値は、集約が必要な場合に文字列から数値型へ自動的に変換されます。 互換性のない入力は、関数がエラーを生成する原因となります。

出力値

JSONPath は、確定パスと不確定パスに分けることができます。
確定パスは、null または単一の一致のみを返すことができます。
不確定パスは、複数の一致を返すことができます。これには、分離されたパス、複数の名前/インデックスのリスト、配列スライス、または式セグメントを含む JSONPath が該当します。
ただし、関数が使用される場合、JSONPath は確定パスになります。関数は常に単一の値を出力するためです。

確定パスは、参照しているオブジェクト/配列/値を返します。
一方、不確定パスは、一致したオブジェクト/配列/値の配列を返します。

JSONPath クエリ結果のプロパティ順序は、内部最適化の方法により、元の JSON のプロパティ順序と一致しない場合があります。
たとえば、JSONPath $.books[1]["author", "title"]["title", "author"] を返す場合があります。
元のプロパティ順序を保持することが重要な場合は、クエリ後の別の処理方法を検討してください。

パスの書式ルール

空白文字(スペース、タブ文字)は、たとえば $[ 'a' ][ 0 ][ ?( $.b == 'c' ) ][ : -1 ].first( ) のように、ブラケット記法のセグメントや式で使用できます。

文字列は、シングルクォート(')またはダブルクォート(")で囲む必要があります。
文字列内では、シングルクォートまたはダブルクォート(どちらで囲んでいるかに応じて)およびバックスラッシュ(\)は、バックスラッシュ(\)文字でエスケープします。

{
  "books": [
    {
      "category": "reference",
      "author": "Nigel Rees",
      "title": "Sayings of the Century",
      "price": 8.95,
      "id": 1
    },
    {
      "category": "fiction",
      "author": "Evelyn Waugh",
      "title": "Sword of Honour",
      "price": 12.99,
      "id": 2
    },
    {
      "category": "fiction",
      "author": "Herman Melville",
      "title": "Moby Dick",
      "isbn": "0-553-21311-3",
      "price": 8.99,
      "id": 3
    },
    {
      "category": "fiction",
      "author": "J. R. R. Tolkien",
      "title": "The Lord of the Rings",
      "isbn": "0-395-19395-8",
      "price": 22.99,
      "id": 4
    }
  ],
  "services": {
    "delivery": {
      "servicegroup": 1000,
      "description": "Next day delivery in local town",
      "active": true,
      "price": 5
    },
    "bookbinding": {
      "servicegroup": 1001,
      "description": "Printing and assembling book in A5 format",
      "active": true,
      "price": 154.99
    },
    "restoration": {
      "servicegroup": 1002,
      "description": "Various restoration methods",
      "active": false,
      "methods": [
        {
          "description": "Chemical cleaning",
          "price": 46
        },
        {
          "description": "Pressing pages damaged by moisture",
          "price": 24.5
        },
        {
          "description": "Rebinding torn book",
          "price": 99.49
        }
      ]
    }
  },
  "filters": {
    "price": 10,
    "category": "fiction",
    "no filters": "no \"filters\""
  },
  "closed message": "Store is closed",
  "tags": [
    "a",
    "b",
    "c",
    "d",
    "e"
  ]
}
JSONPath Type 結果
$.filters.price definite 10
$.filters.category definite fiction
$.filters['no filters'] definite no "filters"
$.filters definite {
"price": 10,
"category": "fiction",
"no filters": "no \"filters\""
}
$.books[1].title definite Sword of Honour
$.books[-1].author definite J. R. R. Tolkien
$.books.length() definite 4
$.tags[:] indefinite ["a", "b", "c", "d", "e" ]
$.tags[2:] indefinite ["c", "d", "e" ]
$.tags[:3] indefinite ["a", "b", "c"]
$.tags[1:4] indefinite ["b", "c", "d"]
$.tags[-2:] indefinite ["d", "e"]
$.tags[:-3] indefinite ["a", "b"]
$.tags[:-3].length() definite 2
$.books[0, 2].title indefinite ["Moby Dick", "Sayings of the Century"]
$.books[1]['author', "title"] indefinite ["Sword of Honour", "Evelyn Waugh"]
$..id indefinite [1, 2, 3, 4]
$.services..price indefinite [154.99, 5, 46, 24.5, 99.49]
$.books[?(@.id == 4 - 0.4 * 5)].title indefinite ["Sword of Honour"]

注: このクエリは、クエリ内で算術演算を使用できることを示しています。これは $.books[?(@.id == 2)].title に簡略化できます。
$.books[?(@.id == 2 \|\| @.id == 4)].title indefinite ["Sword of Honour", "The Lord of the Rings"]
$.books[?(!(@.id == 2))].title indefinite ["Sayings of the Century", "Moby Dick", "The Lord of the Rings"]
$.books[?(@.id != 2)].title indefinite ["Sayings of the Century", "Moby Dick", "The Lord of the Rings"]
$.books[?(@.title =~ " of ")].title indefinite ["Sayings of the Century", "Sword of Honour", "The Lord of the Rings"]
$.books[?(@.price > 12.99)].title indefinite ["The Lord of the Rings"]
$.books[?(@.author > "Herman Melville")].title indefinite ["Sayings of the Century", "The Lord of the Rings"]
$.books[?(@.price > $.filters.price)].title indefinite ["Sword of Honour", "The Lord of the Rings"]
$.books[?(@.category == $.filters.category)].title indefinite ["Sword of Honour","Moby Dick","The Lord of the Rings"]
$.books[?(@.category == "fiction" && @.price < 10)].title indefinite ["Moby Dick"]
$..[?(@.id)] indefinite [
{
"price": 8.95,
"id": 1,
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century"
},
{
"price": 12.99,
"id": 2,
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour"
},
{
"price": 8.99,
"id": 3,
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3"
},
{
"price": 22.99,
"id": 4,
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8"
}
]
$.services..[?(@.price > 50)].description indefinite ["Printing and assembling book in A5 format", "Rebinding torn book"]
$..id.length() definite 4
$.books[?(@.id == 2)].title.first() definite Sword of Honour
$..tags.first().length() definite 5

注: $..tags は不定パスであるため、一致した要素の配列、つまり [["a", "b", "c", "d", "e" ]] を返します。first() は最初の要素、つまり ["a", "b", "c", "d", "e"] を返します。length() はその要素の長さ、つまり 5 を計算します。
$.books[*].price.min() definite 8.95
$..price.max() definite 154.99
$.books[?(@.category == "fiction")].price.avg() definite 14.99
$.books[?(@.category == $.filters.xyz)].title indefinite 注: 一致しないクエリは、definite パスと indefinite パスの両方で NULL を返します。
$.services[?(@.active=="true")].servicegroup indefinite [1001,1000]

注: 真偽値の比較では、テキスト定数を使用する必要があります。
$.services[?(@.active=="false")].servicegroup indefinite [1002]

注: 真偽値の比較では、テキスト定数を使用する必要があります。
$.services[?(@.servicegroup=="1002")]~.first() definite restoration