jsonsql.dev 100% client-side
$.

JSONPath Online Evaluator

Test and filter JSON data with JSONPath expressions — instantly in your browser

Data Map
Quick:
Run a JSONPath expression to see results
Ctrl+Enter evaluate

How to test JSONPath expressions online

jsonsql.dev evaluates JSONPath expressions instantly in your browser. No data is sent to any server — your JSON stays on your machine.

Paste your JSON — copy JSON from your API response, config file, or database export and paste it into the input editor. You can also drag-and-drop a .json file.

Write a JSONPath expression — type your JSONPath query in the expression bar (e.g., $.store.books[*].title). Use the quick-insert buttons for common patterns.

View results — click Run or press Ctrl+Enter. Matching values appear as syntax-highlighted JSON in the results panel. Copy results with one click.

JSONPath syntax reference

JSONPath is to JSON what XPath is to XML — a query language for extracting data from structured documents using path expressions.

Syntax Description Example Result
$ Root element $ The entire JSON document
.key Child access (dot notation) $.store.bicycle {"color":"red","price":199.95}
['key'] Child access (bracket notation) $['store']['bicycle'] Same as dot notation
[n] Array index (0-based, negative for end) $.store.books[0] First book object
[*] Wildcard — all children $.store.books[*].title All book titles as an array
.. Recursive descent (deep scan) $..price All "price" values at any depth
[start:end] Array slice $.store.books[0:2] First two books
[?(expr)] Filter expression $.store.books[?(@.price < 15)] Books cheaper than $15

JSONPath dot notation vs bracket notation

Use dot notation ($.store.name) for simple keys and bracket notation ($['store']['my key']) when property names contain spaces or special characters.

When to use dot notation

  • Simple alphanumeric property names: $.user.name
  • Chaining multiple levels: $.config.database.host
  • Combined with array access: $.users[0].email

When to use bracket notation

  • Keys with spaces: $['first name']
  • Keys with special characters: $['content-type']
  • Keys that look like numbers: $['404']
  • Dynamic or computed keys in code

Side-by-side comparison

// These expressions are equivalent:
$.store.books[0].title
$['store']['books'][0]['title']

// Bracket notation is required for special keys:
$['first name']          // space in key
$['content-type']        // hyphen in key
$['@attributes']['id']   // @ in key

// Dot notation is shorter and more readable:
$.store.bicycle.color    // preferred
$['store']['bicycle']['color']  // equivalent but verbose

JSONPath filter expressions

JSONPath filter expressions use the syntax [?(@.field op value)] where @ refers to the current element being evaluated.

Numeric comparison

// Input
{
  "products": [
    { "name": "Widget", "price": 25 },
    { "name": "Gadget", "price": 75 },
    { "name": "Gizmo", "price": 150 }
  ]
}

// Filter products cheaper than $100
$.products[?(@.price < 100)]
→ [{"name":"Widget","price":25}, {"name":"Gadget","price":75}]

// Filter products $75 or more
$.products[?(@.price >= 75)]
→ [{"name":"Gadget","price":75}, {"name":"Gizmo","price":150}]

String comparison

// Filter by exact string match
$.store.books[?(@.category == "fiction")]
→ Books in the fiction category

// Filter by not equal
$.store.books[?(@.category != "programming")]
→ Books NOT in the programming category

Existence check

// Filter elements that have an "email" field
$.users[?(@.email)]
→ Only users that have an email property

Supported operators

  • == — equal to (strings and numbers)
  • != — not equal to
  • > — greater than
  • < — less than
  • >= — greater than or equal
  • <= — less than or equal
  • @.field (no operator) — existence check

JSONPath wildcard and recursive descent

Wildcards and recursive descent are the most powerful JSONPath features for searching across complex, deeply nested JSON structures.

Wildcard ([*])

The wildcard [*] matches all elements at the current level:

// Get all elements of an array
$[*]                    → all top-level elements

// Get a field from every array element
$.store.books[*].title  → ["The Great Gatsby", "Clean Code", "Design Patterns", "1984"]

// Get all values of an object
$.store.*               → [books_array, bicycle_object]

Recursive descent (..)

The recursive descent operator .. searches for a key at any depth in the JSON tree:

// Find ALL "price" values anywhere in the document
$..price
→ [12.99, 33.49, 41.99, 9.99, 199.95]

// Find all prices under "store" only
$.store..price
→ [12.99, 33.49, 41.99, 9.99, 199.95]

// Find all "title" values anywhere
$..title
→ ["The Great Gatsby", "Clean Code", "Design Patterns", "1984"]

Practical use cases

  • API response extraction$..id collects all IDs from a nested API response without knowing the exact structure.
  • Config file search$..host finds all host configurations across multiple environments.
  • Data validation$..email extracts all email fields to check for valid formats.
  • Error log parsing$..error finds all error messages in a structured log.

JSONPath vs jq vs SQL for querying JSON

Different tools for different needs. Here is how JSONPath compares to jq and SQL for common JSON querying tasks.

Aspect JSONPath jq SQL (on JSON)
Syntax complexity Low — dot/bracket notation Medium — pipe-based functional Low — familiar SELECT/WHERE
Installation required No (browser-based here) Yes (CLI tool) No (browser-based here)
Browser-based Yes (jsonsql.dev) No Yes (jsonsql.dev)
Deep nested access Best ($.a.b.c) Good (.a.b.c) Limited
Recursive search Yes ($..key) Yes (.. | .key?) No
Filter capability Basic ([?(@.x>5)]) Full (select()) Full (WHERE clause)
Aggregation No Yes (length, add, etc.) Yes (COUNT, SUM, AVG)
Learning curve Very low Steep Low (if you know SQL)

Same query in all three syntaxes

// Task: Get titles of books cheaper than $15

// JSONPath
$.store.books[?(@.price < 15)].title

// jq
.store.books[] | select(.price < 15) | .title

// SQL (jsonsql.dev SQL mode)
SELECT title FROM store.books WHERE price < 15

Try the SQL query mode or MongoDB query mode on jsonsql.dev for more advanced querying.

JSONPath in different languages

JSONPath is supported across all major programming languages. Here are code snippets showing how to evaluate JSONPath expressions in each.

JavaScript (jsonpath-plus)

import { JSONPath } from 'jsonpath-plus';

const data = { store: { books: [{ title: 'Gatsby', price: 12.99 }] } };
const result = JSONPath({ path: '$.store.books[*].title', json: data });
console.log(result); // ["Gatsby"]

Python (jsonpath-ng)

from jsonpath_ng.ext import parse

data = {"store": {"books": [{"title": "Gatsby", "price": 12.99}]}}
expr = parse("$.store.books[*].title")
result = [m.value for m in expr.find(data)]
print(result)  # ["Gatsby"]

Java (Jayway JsonPath)

import com.jayway.jsonpath.JsonPath;

String json = "{\"store\":{\"books\":[{\"title\":\"Gatsby\"}]}}";
List<String> titles = JsonPath.read(json, "$.store.books[*].title");
System.out.println(titles); // ["Gatsby"]

Command line (jq equivalent)

# jq uses a different syntax but achieves the same result
cat data.json | jq '.store.books[].title'
# Output: "Gatsby"

# For JSONPath-compatible CLI, use jsonpath-cli (Node.js):
npx jsonpath-cli '$.store.books[*].title' data.json

Related tools

Frequently asked questions

What is the difference between dot notation and bracket notation in JSONPath?

Dot notation ($.store.name) is shorter and works for simple alphanumeric keys. Bracket notation ($['store']['my key']) is required when property names contain spaces, hyphens, or other special characters. Both access the same data.

How do I use recursive descent (..) in JSONPath?

The double-dot (..) searches for a key at any depth in the JSON tree. $..price finds every "price" value in the entire document regardless of nesting depth. $.store..price finds all "price" values under "store". It is equivalent to a depth-first search.

How do I filter a JSON array with JSONPath filter expressions?

Use a filter expression: $[?(@.field == value)]. The @ symbol refers to the current element. For example, $.users[?(@.age > 30)] returns all users older than 30. Supported operators: ==, !=, >, <, >=, <=.

How do I get the last element of a JSON array with JSONPath?

Use a negative index: $[-1]. Negative indices count from the end of the array. $[-1] is the last element, $[-2] is the second-to-last, and so on.

What does the wildcard [*] do in JSONPath?

The wildcard [*] selects all children of the current element. $.employees[*].name returns the name of every employee. $[*] at the root selects all top-level elements of an array.

Does JSONPath support regular expressions?

Standard JSONPath (RFC 9535) supports regex in filter expressions, but implementations vary. The jsonsql.dev evaluator supports comparison operators (==, !=, >, <, >=, <=) and existence checks. For regex matching, consider using the SQL mode with LIKE operators.

How do I select multiple array elements with array slicing?

Use slice syntax [start:end:step]. For example, $[0:3] selects the first 3 elements (indices 0, 1, 2). $[::2] selects every other element. $[1:] selects all elements except the first. Negative indices work too: $[-3:] selects the last 3 elements.

What is the difference between JSONPath and jq syntax?

JSONPath uses $ as the root and dot/bracket notation ($..store.books[0].title), while jq uses a pipe-based functional syntax (.store.books[0].title | length). JSONPath is a read-only query language defined in RFC 9535; jq is a full transformation language with functions, variables, and string interpolation.

How do I check if a field exists using JSONPath?

Use an existence filter: $[?(@.email)] returns all elements that have an email field. This checks for the presence of the key regardless of its value — even null values match. To check for non-null, combine with a comparison: $[?(@.email != null)].

Can I combine multiple filter conditions in JSONPath?

Yes. Use && for AND and || for OR inside filter expressions. For example, $[?(@.age > 25 && @.department == "Engineering")] matches elements where both conditions are true. Parentheses can group conditions for complex logic.