Open jprawiharjo opened 6 months ago
same
Got it
You should use
from jsonpath_ng.ext import parse
instead of
from jsonpath_ng import parse
To use the extensions below you must import from jsonpath_ng.ext.
Using .ext does not solve this
There are 2 options to realize this:
from jsonpath_ng import parse as jpe
from jsonpath_ng.ext import parse as jpx
j = {
"students": [
{"name": "Peter", "gender": "Male", "age": 20},
{"name": "Mary", "gender": "Female", "age": 30},
{"name": "Susan", "gender": "Female", "age": 40}
],
"teachers": [
{"name": "William", "gender": "Male", "age": 30},
{"name": "John", "gender": "Male", "age": 40},
{"name": "Lucy", "gender": "Female", "age": 50}
]
}
jpx_female = jpx('$.*[?gender = "Female"]')
females = jpx_female.find(j)
[f.value for f in females]
Result:
[{'name': 'Mary', 'gender': 'Female', 'age': 30},
{'name': 'Susan', 'gender': 'Female', 'age': 40},
{'name': 'Lucy', 'gender': 'Female', 'age': 50}]
jpe_person = jpe('$.*.[*]') # or jpe('$.*[*]')
females = jpe_person.filter(lambda p: p['gender'] != 'Female', j)
females
Result:
{'students': [{'age': 30, 'gender': 'Female', 'name': 'Mary'},
{'age': 40, 'gender': 'Female', 'name': 'Susan'}],
'teachers': [{'age': 50, 'gender': 'Female', 'name': 'Lucy'}]}
From that filtered dict you can also return the person dicts isolated by applying the person expression:
persons = jpe_person.find(females)
[f.value for f in persons]
Result:
[{'name': 'Mary', 'gender': 'Female', 'age': 30},
{'name': 'Susan', 'gender': 'Female', 'age': 40},
{'name': 'Lucy', 'gender': 'Female', 'age': 50}]
I missed, that jsonpath_ng.ext.parse
also supports filter expressions in a style as seen in the initial post like:
$..[?(@.gender=="Female")]
Anyways with this syntax, the following (with only a instead of a .) works as well for an extended expression: `$.[?(@.gender == "Female")]` Result:
[{'name': 'Mary', 'gender': 'Female', 'age': 30},
{'name': 'Susan', 'gender': 'Female', 'age': 40},
{'name': 'Lucy', 'gender': 'Female', 'age': 50}]
So it's just a matter of addressing the objects within the structure correctly and using .. doesn't seem reasonable to me.
Yet, this works also (not sure it makes sense though):
$..*[?(@.gender == "Female")]
Another option with different (extended) syntax is also:
$.* where $[?gender = "Female"]
This expression can be parsed on https://jsonpath.com/ :
$..[?(@.gender=="Female")]
Exception:
Exception: Parse error at 1:4 near token ? (?)
Example JSON: