Skip to main content

JSONPath Syntax and Operators

Learning Focus

JSONPath is to JSON what XPath is to XML — a path expression language to navigate, select, and filter elements at any depth.

Syntax Reference

ExpressionDescription
$Root element
@Current element (in filter context)
.key or ['key']Child property
..keyRecursive descent — any depth
*Wildcard — all children
[n]Array index (0-based)
[-n]Negative index — from end
[start:end]Array slice
[a,b,c]Union — multiple indices
?(<expr>)Filter expression

Sample Document

{
"store": {
"book": [
{ "category": "reference", "author": "Nigel Rees", "title": "Sayings", "price": 8.95 },
{ "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 },
{ "category": "fiction", "author": "Herman Melville","title": "Moby Dick", "price": 8.99, "isbn": "0-553-21311-3" },
{ "category": "fiction", "author": "J.R.R. Tolkien","title": "LOTR", "price": 22.99,"isbn": "0-395-19395-8" }
],
"bicycle": { "color": "red", "price": 19.95 }
}
}

Practical Queries

$.store.book[*].author → All authors (array)
$..author → All authors at any depth (recursive)
$..price → All prices anywhere in doc
$.store.book[2] → Third book (index 2)
$.store.book[-1] → Last book
$.store.book[0:2] → First two books
$.store.book[?(@.price < 10)] → Books cheaper than 10
$.store.book[?(@.isbn)] → Books with an ISBN field
$.store.book[?(@.category == "fiction")].title → Fiction titles

Filter Operators

OperatorMeaning
==Equal
!=Not equal
< <=Less / less-or-equal
> >=Greater / greater-or-equal
=~Regex match (implementation-dependent)

Python Example

# pip install jsonpath-ng
from jsonpath_ng import parse

data = {"store": {"book": [
{"title": "Book A", "price": 8.95},
{"title": "Book B", "price": 22.00}
]}}

# All titles
titles = [m.value for m in parse("$.store.book[*].title").find(data)]
# ['Book A', 'Book B']

# Books under $10
cheap = [m.value for m in parse("$.store.book[?(@.price < 10)].title").find(data)]
# ['Book A']

Concept Map

Concept Flow

JSONPath
├── $ Root
├── .key Child access
├── ..key Recursive descent
├── * Wildcard
├── [n] Array index
└── ?() Filter expression
└── Comparisons and existence checks

Common Pitfalls

PitfallConsequencePrevention
Off-by-one in array indexWrong elementRemember 0-based indexing
.. on large docsPerformance hitUse explicit path prefix
Filter on non-existent fieldEmpty result, no errorTest with known data first
Mixing JSONPath and jq syntaxWrong resultsJSONPath $..key ≠ jq ..key

What's Next