4 JSONPath機能
概要
このセクションでは、アイテムの値の前処理ステップ内でサポートされるJSONPath機能の概要を説明します。
JSONPathは、ドットで区切られたセグメントで構成されます。
セグメントは、JSON値の名前を表す単純な単語、ワイルドカード文字(*)、または角括弧で囲まれたより複雑な構文の形式を取ることができます。
角括弧で囲まれたセグメントの前のドットは任意であり、省略できます。
| JSONPath example | Description |
|---|---|
$.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より大きいオブジェクトの数を返します。 |
参照: JSONPathでLLDマクロ値の特殊文字をエスケープする。
サポートされているセグメント
| 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 | ブール否定 | ブール値 (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": "地元の町での翌日配達",
"active": true,
"price": 5
},
"bookbinding": {
"servicegroup": 1001,
"description": "A5形式での書籍の印刷および製本",
"active": true,
"price": 154.99
},
"restoration": {
"servicegroup": 1002,
"description": "さまざまな修復方法",
"active": false,
"methods": [
{
"description": "化学洗浄",
"price": 46
},
{
"description": "湿気で損傷したページの圧着",
"price": 24.5
},
{
"description": "破れた本の再製本",
"price": 99.49
}
]
}
},
"filters": {
"price": 10,
"category": "fiction",
"no filters": "no \"filters\""
},
"closed message": "店舗は閉店しています",
"tags": [
"a",
"b",
"c",
"d",
"e"
]
}
| JSONPath | Type | Result |
|---|---|---|
$.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 | ["A5形式での書籍の印刷および製本", "破れた本の再製本"] |
$..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 |