Edited at

JSONPathにおける[*]と..の違い

More than 3 years have passed since last update.


概要

JSONPathの構文で、[*]と..の違いがよくわからなくなったのでまとめる。


JSONPathとは

JSONPath - XPath for JSON : http://goessner.net/articles/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
}
}
}

このとき、bookのpriceの一覧を取得しようとしたときに、

$.store.book..price$.store.book[*].price の何が違うのか。


結論

$.store.book..priceは、bookが配列でなくてもpriceを取得できる。

$.store.book[*].priceは、bookが配列でないとpriceを取得できない。

ただし、どちらも結果は配列で取得できる。

つまり、以下のような場合、$.store.book[*].priceではpriceを取得できない。

{ "store": {

"book": { // bookが配列ではない。
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
"bicycle": {
"color": "red",
"price": 19.95
}
}
}

なので、例えばRSpecでJSONPathを使ってテストを書こうとした場合、

必ず配列である場合には[*]を使って、単体だと配列にならず、複数だと配列になるような場合(そんな設計はそもそもどうなのというのはあるが)、..を使う。