jsonpath

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

More than 1 year has 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を使ってテストを書こうとした場合、
必ず配列である場合には[*]を使って、単体だと配列にならず、複数だと配列になるような場合(そんな設計はそもそもどうなのというのはあるが)、..を使う。