Skip to content
qinhao edited this page Aug 9, 2021 · 5 revisions

JSONPath is a JSON query language that was influenced by Xpath and bears some similarity to jq.

jq, while being more powerful than JSONPath, nevertheless enables one to write queries that are usually as simple as, and sometimes even simpler than, the corresponding JSONPath queries.

For example, the XPath expression:

/store/book[1]/title

would look like this in JSONPath:

$.store.book[0].title

and like this in JSON Pointer:

/store/book/0/title

and like this in jq:

.store.book[0].title

One important point about jq here is that jq is stream-oriented: the jq expression shown above can be run not just against a single object, but also against a stream of objects.

In general, given a stream of JSON entities as input, jq will produce a stream of outputs. The input entities may be any mix of any JSON types, not just objects or arrays.

Concepts

"."

JSONPath distinguishes between the "root object or element" ($) and "the current object or element" (.). jq simply uses . to refer to the current JSON entity and so it is context-dependent: it can refer to items in the input stream of the jq process as a whole, or to the output of a filter. To refer to items in the input stream of the jq process as a whole, one can initially bind "." to a jq variable, e.g. ". as $in".

".."

In jq, the .. filter generates a stream of all the entities at the ends of all paths, including the "." path. The first item generated is in fact the input entity itself.

For example, [1,2] | .. generates three entities, the array itself, and its two components.

Examples

The JSONPath website includes a single-object "database" to illustrate JSONPath queries. With thanks to Stefan Goessner, a copy of that JSON object is appended for ease of reference. The examples in this section can be run against that database.

JSONPath jq Result
$.store.book[*].author .store.book[].author the authors of all books in the store
$..author ..|objects.author all authors (whether of books or not(*))
$.store.* .store # see (**) everything in the store
$.store..price .store|..|objects.price the price of everything in the store (*)
$..book[2] ..|objects|select(has("book")).book[2] the third book mentioned anywhere (*)
$..book[2] ..|objects|.book//empty|.[2] the third book mentioned anywhere (*)
.store.book[2] the third book in the store
$..book[(@.length-1)] ..|objects.book[-1] the last-mentioned book amongst all books (*)
$..book[0,1] ..|objects.book//empty|.[0:2] the first two books (*)
.store.book[0:2] the first two books in the store
$..book[?(@.isbn)] ..|objects|.book//empty | .[] |select(.isbn) all books with an isbn number (*)
.store.book[] | select(.isbn) all books in the store with an isbn number
$..book[?(@.price<10)] ..|objects|.book//empty | .[] |select(.price < 10) all books cheaper than 10 (*)
.store.book[] | select(.price < 10) all books in the store cheaper than 10
.. .. All members of the JSON structure

(*) These queries will locate the items, irrespective of the specific structure of the input.

(**) The jq query

.store|keys

yields ["bicycle", "book"] and thus everything in the store (whether bicycyles, books, or anything else) can be retrieved using:

   .store[ .store|keys[] ]

or even more succinctly:

.store[]

Illustrative Object

{ "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
    }
  }
}
Clone this wiki locally