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