JSONPath RW Extensions
jsonpath-rw-ext extends the capabilities of the jsonpath-rw library by integrating several powerful extensions such as 'len' for list length, 'sorted' for list sorting, 'arithmetic' for mathematical operations, and 'filter' for selective element extraction. These extensions were initially developed to be proposed upstream to jsonpath-rw and persist in jsonpath-rw-ext if not adopted. The library is currently active, with version 1.2.2, though its release cadence appears to be slow or maintenance-focused, with the last update in July 2019.
Warnings
- gotcha jsonpath-rw-ext acts as an extension to jsonpath-rw. Advanced filtering syntax (e.g., `[?()]`) and other extensions are provided by jsonpath-rw-ext, not the base jsonpath-rw library. Attempting to use these features directly with `jsonpath_rw.parse` will result in errors.
- gotcha The classes internal to `jsonpath_rw` that are extended by `jsonpath-rw-ext` are not considered part of its public API. Their structure and naming might change if these extensions are eventually integrated into the upstream `jsonpath-rw` project. Only the JSONPath syntax is guaranteed to remain stable.
- deprecated The `jsonpath-ng` library is presented as a successor, merging `jsonpath-rw` and `jsonpath-rw-ext` functionalities, aiming for broader standard compliance, performance improvements, and enhanced AST API (e.g., node update/removal). For new projects, `jsonpath-ng` might be a more robust and actively developed alternative.
- gotcha When using arithmetic or string operations within JSONPath expressions (e.g., `$.foo + $.bar`), the paths must be fully defined (e.g., `$.field`). If not fully defined, `jsonpath-rw-ext` may incorrectly interpret the expression as a string literal rather than a JSONPath field, leading to unexpected results or empty matches.
- gotcha In some environments (e.g., PySpark), using `jsonpath-rw-ext` has been reported to cause issues related to its dependency `pbr` needing an updated `setuptools` to avoid versioning exceptions.
Install
-
pip install jsonpath-rw-ext
Imports
- parse
import jsonpath_rw_ext expression = jsonpath_rw_ext.parse('$.foo.bar') - ExtentedJsonPathParser
from jsonpath_rw_ext import parser expression = parser.ExtentedJsonPathParser().parse('$.foo.bar') - match
import jsonpath_rw_ext as jp result = jp.match('$.items[*]', {'items': [1, 2, 3]})
Quickstart
import json
import jsonpath_rw_ext
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
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
# Using the 'len' extension to get the number of books
jsonpath_expr_len = jsonpath_rw_ext.parse('$.store.book.`len`')
matches_len = jsonpath_expr_len.find(data)
print(f"Number of books: {matches_len[0].value}")
# Using the 'filter' extension to find books cheaper than 10
jsonpath_expr_filter = jsonpath_rw_ext.parse('$.store.book[?(@.price < 10)]')
matches_filter = [match.value for match in jsonpath_expr_filter.find(data)]
print(f"Books cheaper than 10: {[book['title'] for book in matches_filter]}")
# Using arithmetic extension
jsonpath_expr_arith = jsonpath_rw_ext.parse('$.store.bicycle.price * 2')
matches_arith = jsonpath_expr_arith.find(data)
print(f"Double bicycle price: {matches_arith[0].value}")