Another JSONPath implementation for Python.
Supports:
- Root
$
and current@
node - Child operator
.
or[
...]
- Property access (including single quote
'
and double"
quote delimited names) - Recursive descent
..
- Wildcard
*
- Sets of names/indices
[a,b,c]
- Array slice
[start:end:step]
(including negative values) - Python script expression
(
...)
and filter expression?(
...)
using$
and@
Requires Python 3.5+ and depends on the PyParsing package.
JSONPyth can be git-cloned directly from Github and installed along with its
dependencies using pip
:
$ pip install git+https://github.com/Frimkron/JSONPyth#egg=JSONPyth
Or the source can be downloaded manually and then installed by running the
setup.py
script:
$ python setup.py install
First parse some JSON data into a Python structure, for example using the json package from the standard library:
import json
# parse some JSON from a string
data = json.loads("""
{
"cakes": [
{ "name": "red velvet", "rating": 4.5 },
{ "name": "battenberg" },
{ "name": "jaffa cakes", "rating": 5.0 }
],
"biscuits": [
{ "name": "bourbon", "rating": 5.0 },
{ "name": "custard cream", "rating": 3.5 },
{ "name": "pink wafer", "rating": null },
{ "name": "nice" }
]
}
""")
Then the data can be queried with a JSONPath expression:
from jsonpyth import jsonpath
result = jsonpath(data, '$.biscuits[*].rating')
for r in result:
print(r)
The example above would print the following output:
5
3.5
None
By default the value of each result is returned. To obtain the normalised path
of each result instead, set the result_type
parameter to RESULT_TYPE_PATH
,
or RESULT_TYPE_BOTH
can be used to return 2-tuples containing both the value
and the path:
from jsonpyth import jsonpath, RESULT_TYPE_BOTH
result = jsonpath(data, '$.biscuits[*].rating', result_type=RESULT_TYPE_BOTH):
for r in result:
print(r)
Output:
(5, '$["biscuits"][0]["rating"]')
(3.5, '$["biscuits"][1]["rating"]')
(None, '$["biscuits"][2]["rating"]')
A JSONPath script expression (enclosed in parentheses (...)
) can be used to
evaluate a Python statement to provide a dictionary key as a string, or list
index as a number. Return values of other types will be ignored.
As parentheses are used to delimit the expression, parentheses used in the
script itself must be escaped with a backslash \
.
The special symbols @
(current node) and $
(root node) will be substituted
for variables named __current
and __root
respectively, using a simple text
replacement before the statement is evaluated. To use a literal @
or $
in
the script, it must be escaped with two backslashes \\
. Note that a string
literal will recognise \\
as an escaped backslash; in such a case each
backslash must be further escaped ("\\\\@"
) or else a raw literal used
(r"\\@"
).
An example script expression:
result = jsonpath(data, r'$.cakes[(len\(@\)-1)].name')
for r in result:
print(r)
Output:
jaffa cakes
NOTE JSONPyth calls eval
to evaluate Python script, and so is unsafe
to use for JSONPath expressions from untrusted sources.
Similar to expressions, filters ( ?(...)
) use a Python statement to test
whether to include a node or not. The truthiness of the resulting value will be
tested using bool
, and if False
the node will be omitted.
Example:
result = jsonpath(data, r'$[*][?(@["name"].startswith\("b"\))]')
for r in result:
print(r)
Output:
{"name": "battenberg"}
{"name": "bourbon", "rating": 5}
JSONPyth was written by Mark Frimston and is licenced using the the MIT
licence. The full text of this licence can be found in the LICENCE.txt
file.