JSONPath Syntax -- How to Query and Extract Data from JSON

Learn JSONPath syntax to extract specific values from complex JSON structures using dot notation and bracket expressions.

JSONPath is the JSON equivalent of XPath for XML. It provides a powerful syntax for querying and extracting data from complex JSON documents without having to parse the entire structure manually. Whether you're working with APIs, configuration files, or data transformation pipelines, mastering JSONPath can save you countless hours of boilerplate parsing code.

What is JSONPath?

JSONPath is a query language that allows you to navigate and select nodes in a JSON document using a simple path notation. Instead of writing loops and conditionals to dig through nested objects and arrays, you can express your intent declaratively with a path expression.

Consider this product catalog JSON:

{
  "store": {
    "name": "Tech Market",
    "products": [
      {
        "id": 1,
        "name": "Laptop",
        "price": 999.99,
        "category": "electronics",
        "inStock": true
      },
      {
        "id": 2,
        "name": "Mouse",
        "price": 29.99,
        "category": "accessories",
        "inStock": true
      },
      {
        "id": 3,
        "name": "Monitor",
        "price": 399.99,
        "category": "electronics",
        "inStock": false
      }
    ]
  }
}

With JSONPath, you can extract specific information from this structure elegantly and efficiently.

JSONPath Basics: Root and Navigation

Every JSONPath expression starts with the root element, represented by a dollar sign ($). From there, you navigate through the JSON structure using either dot notation or bracket notation.

Dollar Sign - The Root

The $ symbol represents the root of the JSON document:

$ => The entire document

Dot Notation

Dot notation uses a period (.) followed by the property name to access object properties:

$.store => The "store" object
$.store.name => "Tech Market"
$.store.products => The products array

This is the most readable format when you're accessing known property names.

Bracket Notation

Bracket notation uses square brackets and can handle property names with special characters or spaces:

$['store'] => The "store" object
$['store']['name'] => "Tech Market"
$['store']['products'][0] => First product object
$['store']['products'][0]['name'] => "Laptop"

Bracket notation is necessary when property names contain spaces, special characters, or start with numbers.

Array Indexing and Slicing

When working with JSON arrays, JSONPath provides intuitive syntax for selecting specific elements:

$.store.products[0] => First product
$.store.products[-1] => Last product
$.store.products[0,2] => First and third products
$.store.products[0:2] => Products at index 0 and 1 (slice)
$.store.products[1:] => All products from index 1 onward
$.store.products[:2] => First two products

The slice notation works like Python slicing, where the end index is exclusive.

Wildcards - Select All Elements

The asterisk (*) wildcard matches any property or array element:

$.store.products[*].name => ["Laptop", "Mouse", "Monitor"]
$.store.products[*].price => [999.99, 29.99, 399.99]
$.store.* => All properties of the store object

This is powerful for extracting all values of a specific property across multiple objects.

Recursive Descent - Search at Any Depth

The double-dot (..) operator performs a recursive search at any depth in the document structure:

$..name => ["Tech Market", "Laptop", "Mouse", "Monitor"]
$..price => [999.99, 29.99, 399.99]
$..inStock => [true, true, false]

Recursive descent is invaluable when you need to find all instances of a property regardless of nesting level.

Filter Expressions - Conditional Selection

Filter expressions let you select elements based on conditions. The syntax is ?(@.property operator value):

$.store.products[?(@.price > 100)] => Products costing more than $100
$.store.products[?(@.inStock == true)] => Only in-stock items
$.store.products[?(@.category == 'electronics')] => Electronics category

Common comparison operators include:

  • == for equality
  • != for inequality
  • <, <=, >, >= for numeric comparisons
  • =~ for regex matching (in some implementations)

You can also combine conditions:

$.store.products[?(@.price > 50 && @.inStock == true)]

This selects products that cost more than $50 AND are currently in stock.

Practical Examples

Let's walk through real-world scenarios using our product catalog:

Get all product names:

$.store.products[*].name

Result: ["Laptop", "Mouse", "Monitor"]

Find expensive products (over $200):

$.store.products[?(@.price > 200)]

Result: Returns the Laptop and Monitor objects with all their properties.

Get in-stock product prices:

$.store.products[?(@.inStock)][*].price

Result: [999.99, 29.99]

Get the first product's category:

$.store.products[0].category

Result: "electronics"

Find all properties named 'id' in the document:

$..id

Result: [1, 2, 3]

JSONPath vs XPath

If you're familiar with XPath for XML, you'll find JSONPath conceptually similar. The main differences:

  • XPath uses / for path separation; JSONPath uses . or []
  • XPath has // for recursive descent; JSONPath uses ..
  • Both support wildcards and predicates, but the syntax differs slightly
  • JSONPath is simpler because JSON structure is less complex than XML

Implementation Considerations

Different programming languages and libraries implement JSONPath with varying levels of compliance to the standard. Some important points:

JavaScript/Node.js: Libraries like jsonpath and jp provide implementations. The jp library is particularly popular for command-line use.

Python: The jsonpath-ng and jsonpath-rw libraries offer comprehensive JSONPath support.

Java: com.jayway.jsonpath:json-path is the standard implementation.

Go: github.com/PainterArtisan/jsonpath and others are available.

Always check your library's documentation, as filter expression syntax can vary between implementations.

Common Pitfalls

Array indices: Remember that array indices are zero-based, and slicing is exclusive of the end index.

Property names with special characters: Always use bracket notation for these cases instead of dot notation.

Filter expression syntax: The exact syntax for filters varies by library. Some require double parentheses, others require different operators.

Recursive descent performance: Using $..property on large documents can be slow. Be as specific as possible.

Tools and Resources

Many online tools make experimenting with JSONPath easier. Paste your JSON and try different expressions interactively to verify your queries before using them in production code. Browser-based JSONPath evaluators and command-line tools are freely available and invaluable for learning and debugging.

Conclusion

JSONPath transforms how you interact with JSON data. Instead of writing nested loops and null checks, you can express data extraction intent clearly and concisely. Start with simple dot notation and gradually incorporate wildcards, filters, and recursive descent as you tackle more complex queries. Your code will be cleaner, more readable, and easier to maintain.

Related Tools