JSON Path Syntax: Complete Guide with Examples
What is JSON Path?
JSON Path is a query language for JSON, similar to how XPath is used for XML. It allows you to extract specific data from JSON documents using a concise, expressive syntax. Whether you're working with APIs, configuration files, or complex data structures, JSON Path helps you navigate and filter JSON data efficiently.
Originally proposed by Stefan Goessner in 2007, JSON Path has become a standard tool in many programming ecosystems. Libraries exist for JavaScript, Python, Java, PHP, and many other languages.
Basic Syntax and Operators
The Root Element: $
Every JSON Path expression starts with $, which represents the root of the JSON document.
{
"store": {
"name": "Book Store",
"books": [
{"title": "Book A", "price": 10},
{"title": "Book B", "price": 20}
]
}
}
// JSON Path expression
$.store.name // Returns: "Book Store"
// JavaScript equivalent using lodash
_.get(data, 'store.name');
Current Node: @
The @ symbol refers to the current node being processed, especially useful inside filters.
// Find books with price greater than 15
$.store.books[?(@.price > 15)]
// The @ refers to each book object during iteration
Wildcard: *
The asterisk matches all elements at the current level.
// Get all properties of the store object
$.store.*
// Get all book titles
$.store.books[*].title
Dot Notation vs Bracket Notation
JSON Path supports two styles for accessing properties:
Dot Notation (cleaner, preferred when keys are simple):
$.store.name
$.store.books[0].title
Bracket Notation (required for special characters or dynamic keys):
$['store']['name']
$['store']['books'][0]['title']
// Useful when key contains spaces or special characters
$['user settings']['theme color']
Array Access and Slicing
Index Access
// First book
$.store.books[0]
// Last book (using -1 is not standard, but some implementations support it)
// Standard approach: use length - 1 in your code
Array Slices
The slice syntax [start:end:step] allows you to extract ranges from arrays.
// First two books
$.store.books[0:2]
// Every other book starting from index 0
$.store.books[0:4:2]
// From index 1 to end
$.store.books[1:]
Slice Parameters:
| Parameter | Description | Default |
|---|---|---|
| start | Starting index (inclusive) | 0 |
| end | Ending index (exclusive) | Array length |
| step | Step size | 1 |
Filters: The Powerful ?() Syntax
Filters allow you to select items based on conditions. This is where JSON Path becomes truly powerful.
Basic Comparisons
// Books cheaper than 15
$.store.books[?(@.price < 15)]
// Books with a specific title
$.store.books[?(@.title == 'Book A')]
Logical Operators
// Books that are cheap AND fiction
$.store.books[?(@.price < 15 && @.category == 'fiction')]
// Books that are either cheap OR on sale
$.store.books[?(@.price < 10 || @.onsale == true)]
Supported Operators
| Operator | Description | Example |
|---|---|---|
== | Equal | ?(@.price == 10) |
!= | Not equal | ?(@.type != 'ebook') |
< | Less than | ?(@.price < 20) |
<= | Less or equal | ?(@.rating <= 4.5) |
> | Greater than | ?(@.price > 10) |
>= | Greater or equal | ?(@.pages >= 300) |
=~ | Regex match | ?(@.title =~ /book/i) |
in | In array | ?(@.category in ['fiction','drama']) |
nin | Not in array | ?(@.status nin ['outdated','deleted']) |
Existential Checks
// Books that have an 'isbn' field
$.store.books[?(@.isbn)]
// Books that DON'T have a 'discount' field
$.store.books[?!@.discount]
Recursive Descent: ..
The double dot operator searches for matching nodes at any depth in the tree.
// Find all price values anywhere in the document
$.store..price
// Find all objects that have a 'title' field
$..title
Warning: Recursive descent can be expensive on large documents. Use it judiciously.
JSON Path vs XPath: A Comparison
| Feature | JSON Path | XPath |
|---|---|---|
| Data Format | JSON | XML |
| Root | $ | / |
| Current Node | @ | . |
| Wildcard | * | * |
| Filter | ?() | [] with predicates |
| Recursive | .. | // |
| Array Index | [0] | [1] (XPath is 1-indexed) |
| Attribute Access | .name | @name |
Example Comparison
JSON Path:
$.store.books[?(@.price < 15)].title
XPath equivalent:
/store/books[price < 15]/title
Practical Examples
Example 1: API Response Parsing
{
"data": {
"users": [
{"id": 1, "name": "Alice", "active": true, "role": "admin"},
{"id": 2, "name": "Bob", "active": false, "role": "user"},
{"id": 3, "name": "Charlie", "active": true, "role": "user"}
],
"total": 3
}
}
// Get all active user names
$.data.users[?(@.active == true)].name
// Result: ["Alice", "Charlie"]
// Get admin user IDs
$.data.users[?(@.role == 'admin')].id
// Result: [1]
Example 2: Configuration Extraction
{
"environments": {
"dev": {"api_url": "dev.api.com", "debug": true},
"prod": {"api_url": "api.com", "debug": false}
}
}
// Get all API URLs
$.environments.*.api_url
// Result: ["dev.api.com", "api.com"]
// Check if any environment has debug enabled
$.environments[?(@.debug == true)]
Common Pitfalls and Tips
- Indexing starts at 0 (unlike XPath which starts at 1)
- String comparisons are case-sensitive unless you use regex with
iflag - Not all implementations support all features — check your library's documentation
- Use
..sparingly on large documents as it traverses the entire tree - Filters can only be used on arrays, not objects
Testing JSON Path Expressions
You can test JSON Path expressions using:
- Online evaluators like jsonpath.com
- Browser console with libraries like
jsonpath-plus - Node.js with
jsonpathorjsonpath-pluspackages
npm install jsonpath-plus
import { JSONPath } from 'jsonpath-plus';
const result = JSONPath({ path: '$.store.books[*].title', json: data });
console.log(result); // ['Book A', 'Book B']
Related Tools
- JSON Formatter — Format and validate JSON data