h2non / jsonpath-ng

Finally, a JSONPath implementation for Python that aims to be standard compliant. That's all. Enjoy!
Apache License 2.0
564 stars 85 forks source link

Add negation of relative existence queries #168

Open jg-rp opened 2 months ago

jg-rp commented 2 months ago

This pull request implements the not operator (!) for negating a relative query when testing for existence. This is a potential solution for #167.

Sticking with example data from #167, this example selects values from data that don't contain a type property.

from jsonpath_ng.ext import parse

data = [
    {"name": "foo", "data": [{"value": "bar"}]},
    {"name": "foo", "data": [{"value": "bar", "type": "foo"}]},
]

query = parse("$[?!@..['type']]")  # or "$[?!data[*].type]"
matches = query.find(data)

print([m.value for m in matches])
# [{'name': 'foo', 'data': [{'value': 'bar'}]}]

To keep this PR small, I've deliberately avoided implementing logical negation for other filter expression types and any refactoring of ext.filter.Expression.

michaelmior commented 1 month ago

@jg-rp Thanks! One issue is that you change to the find function can cause returning a boolean instead of a list of results. I think something like the below should work.

         if self.op == "!":
             # Negated relative query existence test
-            return not datum
+            if not datum:
+                return [datum]
+            else:
+                return []
michaelmior commented 1 month ago

It would also be nice if you could add your example above to the README.