JSONPath
XML の利点としてよく強調されるのは、XML 文書を分析し、変換し、選択的にデータを抽出するための豊富なツールが利用可能であることであり、XPathはこのような強力なツールの一つ。
XPath4JSON
- 特別なスクリプトを作成することなく、クライアント側でJSON構造体を対話的に検索し、データを抽出することができる
- クライアントから要求されたJSONデータは、サーバー上で必要な部分だけに縮小され、サーバーレスポンスの帯域幅を最小限に抑えることができる
Wiremockで、Jsonリクエストのマッピングを記載する際にも使用する。
Wiremockについては以下の記事参照。
olafnosuke.hatenablog.com
JSONPathの書き方
オンラインのツールでJSONPathの動作検証も可能
https://jsonpath.com/
JSONPath式は、XPath式がXML文書と組み合わせて使用されるのと同じように、常にJSON構造を参照する。
JsonPathの「ルートメンバーオブジェクト」は、オブジェクトや配列に関わらず、常に$
と表記される。
JSONPathはdot–notationとbracket–notationの2つの書き方がある。
dot–notation:$.store.book[0].title
bracket–notation:$['store']['book'][0]['title']
JSONPath構文要素
要素 | 説明 |
---|---|
$ | ルート要素。 |
@ | 現在の要素。 |
.or [] | 子要素 |
.. | ディープスキャン。名前が必要な場所ならどこでも利用可能。 |
* | ワイルドカード。名前または数値が必要な場所で利用可能。 |
[ |
配列のインデックス |
[start:end:step] | 配列の分割 |
[?( |
フィルタリングの式。式はbooleanで評価されなければならない。 |
関数
関数はパスの末尾で呼び出すことができる。関数への入力はパス式の出力であり、関数の出力は関数自身によって決定される。
関数 | 説明 | 出力型 |
---|---|---|
min() | 数値の配列の最小値を返す | Double |
max() | 数値の配列の最大値を返す | Double |
avg() | 数値の配列の平均値を返す | Double |
stddev() | 数値の配列の標準偏差値を返す | Double |
length() | 配列の長さを返す | Integer |
sum() | 数値の配列の合計値を返す | Double |
keys() | プロパティキー返す | Set |
concat(X) | 新しい項目を連結したJSONPathを返す | 入力と同じ |
append(X) | jsonパスの配列に項目を追加する | 入力と同じ |
first() | 配列の最初の要素を返す | 配列に依存 |
last() | 配列の最後の要素を返す | 配列に依存 |
index(X) | インデックスを持つ配列の項目を返す。X が負の場合は,逆から取る。 | 配列に依存 |
フィルタで使用可能な演算子
フィルタは、配列のフィルタリングに使われる論理式である。典型的なフィルタは [?(@.age > 18)]
で、@
は現在処理中の項目を表す。
より複雑なフィルターは、論理演算子 &&
や ||
を使って作ることができる。
文字列リテラルは、シングルクォートまたはダブルクォートで囲む必要があります([?(@.color == 'blue')] または [?(@.color == "blue")]
)。
演算子 | 説明 |
---|---|
== | 左と右は等しい(ただし、1は'1'と等しくない) |
!= | 左と右は別物 |
< | 左は右より小さい |
<= | 左は右より小さいか等しい |
> | 左は右より大きい |
>= | 左は右より大きいか等しい |
=~ | 左は正規表現にマッチする。[?(@.name =~ /foo.*?/i)] |
in | 左は右に存在する。[?(@.size in ['S', 'M'])] |
nin | 左は右に存在しない |
subsetof | 左は右の部分集合。[?(@.sizes subsetof ['S', 'M', 'L'])] |
anyof | 左は右と交差する。[?(@.sizes anyof ['M', 'L'])] |
noneof | 左と右は交差しない。[?(@.sizes noneof ['M', 'L'])] |
size | 左のサイズ(配列または文字列)は右のサイズと一致する |
empty | 左のサイズ(配列または文字列)は右のサイズと一致する |
JSONPathサンプル
{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }
JSONPath | 結果 |
---|---|
$.store.book[*].author | ストア内のすべての本の筆者 |
$..author | 全ての筆者 |
$.store.* | ストア内の全ての要素(本も自転車も) |
$.store..price | ストア内の全ての価格 |
$..book[2] | 3冊目の本 |
$..book[(@.length-1)] $..book[-1:] |
最後の本 |
$..book[0,1] $..book[:2] |
最初の2冊の本 |
$..book[?(@.isbn)] | isbnを持つ本 |
$..book[?(@.price<10)] | priceが10より安い本 |
$..* | すべての要素 |
$..book.length() | 本の数 |
参考
https://github.com/json-path/JsonPath
https://goessner.net/articles/JsonPath/