JSON & JSONPath Reference

JSON and JSONPath reference — syntax, data types, nesting, array notation. $.store.book[0].title — JSONPath expressions with examples. Complete JSON format reference.

9 min read

What it is

JSON is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. JSONPath is a query language for JSON, similar to XPath for XML.

Installation

JSON is a data format, not a tool that needs installation. Most programming languages have built-in support for parsing and generating JSON.

JSONPath implementations are typically libraries within programming languages. Here are common ways to use JSONPath:

JavaScript (Node.js/Browser):

npm install jsonpath
# or
yarn add jsonpath

Import into your project:

const jsonpath = require('jsonpath');
// or
import jsonpath from 'jsonpath';

Python:

pip install jsonpath-ng

Import into your project:

from jsonpath_ng import jsonpath, parse

Command Line (using jq and jsonpath-ng for piping): jq is a powerful command-line JSON processor. While jq has its own powerful filtering language, you can pipe JSON to jq which can then be processed by a JSONPath library.

Install jq:

# Linux (Debian/Ubuntu)
sudo apt-get update && sudo apt-get install jq

# Linux (Fedora)
sudo dnf install jq

# macOS
brew install jq

# Windows (using Chocolatey)
choco install jq

Core Concepts

  • JSON Structure: JSON data is built on two structures:
    • Objects: A collection of key/value pairs. Keys are strings, values can be strings, numbers, booleans, arrays, objects, or null. Enclosed in curly braces {}.
    • Arrays: An ordered list of values. Values can be any valid JSON type. Enclosed in square brackets [].
  • JSONPath Syntax: JSONPath expressions select nodes within a JSON document.
    • Root: $ represents the root object/element.
    • Dot Notation: . is used to access object members by key (e.g., $.store.book[0].title).
    • Bracket Notation: [] is used to access object members by key or array elements by index. It’s also used for wildcards and filters (e.g., $.store['book'][0].title).
    • Wildcard: * selects all elements in an object or array.
    • Recursive Descent: .. selects all descendants of the current node.
    • Array Slice: [start:end:step] selects a range of array elements.
    • Filter Expression: ?() filters elements based on a condition.

Commands / Usage

This section focuses on how to use JSONPath expressions. The examples assume you have a JSON object available.

Example JSON Data:

{
  "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
    }
  },
  "expensive": 10
}

Selecting Elements

  • Select the root element:

    $
    

    Explanation: Returns the entire JSON document.

  • Select the store object:

    $.store
    

    Explanation: Returns the object under the store key.

  • Select the book array:

    $.store.book
    

    Explanation: Returns the array under the book key within store.

  • Select the first book in the array:

    $.store.book[0]
    

    Explanation: Returns the first element (index 0) of the book array.

  • Select the title of the first book:

    $.store.book[0].title
    

    Explanation: Returns the title property of the first book.

  • Select the title of the second book using bracket notation:

    $.store.book['1']['title']
    

    Explanation: Equivalent to $.store.book[1].title, using bracket notation for both array index and object key.

Wildcards and Recursive Descent

  • Select all books:

    $.store.book[*]
    

    Explanation: Returns all elements within the book array.

  • Select all authors of all books:

    $.store.book[*].author
    

    Explanation: Returns the author property for every element in the book array.

  • Select all titles of all books (using recursive descent):

    $..title
    

    Explanation: Returns all values associated with the title key anywhere in the document.

  • Select all prices from the store (books and bicycle):

    $.store..price
    

    Explanation: Returns all price values found within the store object and its descendants.

Array Slicing

  • Select books from index 1 onwards:

    $.store.book[1:]
    

    Explanation: Returns elements from index 1 to the end of the book array.

  • Select books up to (but not including) index 2:

    $.store.book[:2]
    

    Explanation: Returns elements from the beginning up to (but not including) index 2.

  • Select books from index 1 up to (but not including) index 3:

    $.store.book[1:3]
    

    Explanation: Returns elements from index 1 up to (but not including) index 3.

  • Select every second book:

    $.store.book[::2]
    

    Explanation: Returns elements with a step of 2 (0th, 2nd, etc.).

  • Select books from index 1 with a step of 2:

    $.store.book[1::2]
    

    Explanation: Returns elements starting from index 1 with a step of 2 (1st, 3rd, etc.).

Filter Expressions

  • Select all books with a price less than 10:

    $.store.book[?(@.price < 10)]
    

    Explanation: Filters the book array, returning only elements where the price is less than 10. @ refers to the current element being processed.

  • Select all books with a price greater than or equal to 10:

    $.store.book[?(@.price >= 10)]
    

    Explanation: Filters the book array for prices greater than or equal to 10.

  • Select all fiction books:

    $.store.book[?(@.category == 'fiction')]
    

    Explanation: Filters the book array for elements where the category is 'fiction'.

  • Select all books by Evelyn Waugh:

    $.store.book[?(@.author == 'Evelyn Waugh')]
    

    Explanation: Filters the book array for the specific author.

  • Select all books that have an ISBN:

    $.store.book[?(@.isbn)]
    

    Explanation: Filters the book array, returning elements that have an isbn key (even if its value is null or empty, it must exist).

  • Select the titles of all books with a price less than 10:

    $.store.book[?(@.price < 10)].title
    

    Explanation: First filters for books under $10, then selects the title from the resulting books.

  • Select books with price less than 10 OR category is reference:

    $.store.book[?(@.price < 10 || @.category == 'reference')]
    

    Explanation: Uses the OR operator || to combine conditions.

  • Select books with price less than 10 AND category is fiction:

    $.store.book[?(@.price < 10 && @.category == 'fiction')]
    

    Explanation: Uses the AND operator && to combine conditions.

  • Select books with price between 10 and 20 (inclusive):

    $.store.book[?(@.price >= 10 && @.price <= 20)]
    

    Explanation: Uses a range check with AND operators.

Combining Expressions

  • Select the author of the first book:

    $.store.book[0].author
    

    Explanation: Direct path selection.

  • Select the price of the bicycle:

    $.store.bicycle.price
    

    Explanation: Direct path selection.

  • Select all items that have a price (books and bicycle):

    $..*[?(@.price)]
    

    Explanation: This is a bit broad. It looks for any object * that has a price key. A more precise way for this specific JSON might be $.store.book[?(@.price)] and $.store.bicycle. For a general solution across unknown structures, recursive descent is often used.

  • Select the titles of all books where the author is Herman Melville or J. R. R. Tolkien:

    $.store.book[?(@.author == 'Herman Melville' || @.author == 'J. R. R. Tolkien')].title
    

    Explanation: Filters for specific authors and then extracts their titles.

Common Patterns

  • Using jq to pipe JSON and filter with JSONPath expressions: While jq has its own powerful filtering language, you can combine it with JSONPath logic by using jq to extract parts of the JSON and then processing those parts. For direct JSONPath queries on the command line, tools like jsonpath-cli or Python scripts are common.

    Example using jq to select titles of books with price > 10:

    echo '{
      "store": {
        "book": [
          {"title": "Book A", "price": 5},
          {"title": "Book B", "price": 15}
        ]
      }
    }' | jq '.store.book[] | select(.price > 10) | .title'
    

    Explanation: This uses jq’s own filtering. For a pure JSONPath command-line tool, you’d typically pipe the JSON to that tool.

    Example using a Python script for JSONPath on the command line: Save the following as jp.py:

    import sys
    import json
    from jsonpath_ng import jsonpath, parse
    
    if __name__ == "__main__":
        data = json.load(sys.stdin)
        jsonpath_expression_str = sys.argv[1]
        jsonpath_expression = parse(jsonpath_expression_str)
        matches = jsonpath_expression.find(data)
        results = [match.value for match in matches]
        print(json.dumps(results, indent=2))
    

    Then run:

    echo '{ ... your json ... }' | python jp.py "$.store.book[?(@.price > 10)].title"
    

    Explanation: This script reads JSON from stdin, takes a JSONPath expression as a command-line argument, and prints the results as JSON.

  • Extracting all keys from an object:

    $.store.*
    

    Explanation: Selects all values directly under store. If you want the keys themselves, you’d typically use programmatic iteration or a tool like jq (jq 'keys').

  • Finding a specific book by ISBN:

    $.store.book[?(@.isbn == '0-553-21311-3')]
    

    Explanation: Filters the book array to find the book with a matching ISBN.

  • Getting the price of the most expensive book: This requires a two-step process or a more advanced JSONPath implementation that supports aggregation or sorting, which is not standard. A common approach is to filter and then process the results.

    First, get all book prices:

    $.store.book[*].price
    

    Then, use a programming language or tool to find the maximum value from the resulting list.

    Using jq to find the max price:

    echo '{ ... your json ... }' | jq '[.store.book[].price] | max'
    

    Explanation: jq extracts all prices into an array [...] and then applies the max function.

Gotchas

  • Implementation Differences: JSONPath is a specification, and different libraries (e.g., jsonpath-ng in Python, jsonpath in JavaScript) might have slight variations in syntax or feature support, especially for advanced filtering or recursive descent. Always check the documentation for your specific implementation.
  • Filter Expression Syntax (@): The @ symbol within filter expressions ?() refers to the current node being processed. Forgetting it or misplacing it is a common error.
  • Recursive Descent (..) Performance: While powerful, .. can be computationally expensive on very large or deeply nested JSON structures as it traverses the entire tree. Use it judiciously.
  • Return Type: Some JSONPath implementations might return a list of matches even if only one item is expected. Always be prepared to handle a list, even if you query for a single specific element.
  • Boolean Logic in Filters: Ensure correct use of && (AND) and || (OR) operators within filter expressions. Parentheses () can be used for grouping conditions if needed, though support varies.
  • Array Indexing: JSONPath array indexing is 0-based, just like in most programming languages.
  • Quoting in Filters: String literals within filter expressions must be quoted (e.g., 'fiction'). Numeric literals do not need quotes.
  • Dot vs. Bracket Notation: While often interchangeable for simple property access (e.g., $.store.book vs $.store['book']), bracket notation is essential when keys contain special characters or spaces, or when using variables as keys.