Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter expression cannot be parsed properly #162

Open
jprawiharjo opened this issue Jan 18, 2024 · 5 comments
Open

Filter expression cannot be parsed properly #162

jprawiharjo opened this issue Jan 18, 2024 · 5 comments

Comments

@jprawiharjo
Copy link

This expression can be parsed on https://jsonpath.com/ :

$..[?(@.gender=="Female")]

Exception: Exception: Parse error at 1:4 near token ? (?)

Example JSON:

{
            "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}
            ]
        }
@smithumble
Copy link

same

@smithumble
Copy link

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.

@jprawiharjo
Copy link
Author

Using .ext does not solve this

@e-d-n-a
Copy link

e-d-n-a commented May 5, 2024

There are 2 options to realize this:

Common code:

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}
            ]
        }

1. Using a single expression and with same isolated output as with jsonpath.com:

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}]

2. By using a filter on an expression for persons:

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}]

@e-d-n-a
Copy link

e-d-n-a commented May 5, 2024

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"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants