freestrings / jsonpath

JsonPath engine written in Rust. Webassembly and Javascript support too
MIT License
122 stars 37 forks source link

Support Tilde #69

Open omid opened 3 years ago

omid commented 3 years ago

I would like to get the keys of the matching objects. For example, when I have the following JSON:

{
   "a": {
       "check": true
   },
   "b": {
       "check": true
   },
   "c": {
       "check": false
   }
}

I want to get ["a","b"] with the following selector: $[?(@.check==true)]~

I know it's Jsonpath-Plus. But does this library support it? Is there any plan to go that way? Is there any way I achieve my goal with the current code?

cburgmer commented 3 years ago

It seems the ~ operator is meant to select part of the path and not a value from the JSON document. I remember a discussion a while back with some of the people who are interested in identifying a standard around JSONPath where we mostly were in favour of sticking to the value aspect of JSONPath and not getting into the more complex transformation aspect. Having said that, most libraries that implement JSONPath also return the list of paths that lead to the selected values.

oshadmi commented 3 years ago

@cburgmer

Having said that, most libraries that implement JSONPath also return the list of paths that lead to the selected values.

Such as this?

args.resultType ("VALUE"|"PATH"):
    causes the result to be either matching values (default) or normalized path expressions.

For controlling the result type, could also consider inline/embedded flags (as regular expression inline flags, such as (?s) or (?i)), which doesn't require API changes and, in addition, some users may find more comfortable than adding arguments, although it could slightly cost in performance.

When path includes wildcard, union, recursive descent or slice, the need for getting the concrete paths seems even more justified.

cburgmer commented 3 years ago

Having said that, most libraries that implement JSONPath also return the list of paths that lead to the selected values.

Such as this?

args.resultType ("VALUE"|"PATH"):
    causes the result to be either matching values (default) or normalized path expressions.

Exactly. For example, I implemented this in Clojure: https://github.com/gga/json-path#usage (compare json-path/at-path to json-path/query).

For controlling the result type, could also consider inline/embedded flags (as regular expression inline flags, such as (?s) or (?i)), which doesn't require API changes and, in addition, some users may find more comfortable than adding arguments, although it could slightly cost in performance.

I am not sure I fully understand, but it seems you are arguing for extending the JSONPath syntax to include a query to extract the path, whereas how I understand Goessner and also have seen this in other implementations, you would instead call just a different API.

When path includes wildcard, union, recursive descent or slice, the need for getting the concrete paths seems even more justified.

Agreed.

emmanuelkeller commented 3 years ago

Adding reference regarding the nodes library jsonpath-plus This library introduces two operators:

This can be tested online with this JSON path evaluator. If you use the following JSON path: $.address.*~, you will get an extraction of the keys:

[
  "streetAddress",
  "city",
  "postalCode"
]
deitmerit commented 3 years ago

Adding reference regarding the nodes library jsonpath-plus This library introduces two operators:

  • ^ for grabbing the parent of a matching item
  • ~ for grabbing property names of matching items (as array)

This can be tested online with this JSON path evaluator. If you use the following JSON path: $.address.*~, you will get an extraction of the keys:

[
  "streetAddress",
  "city",
  "postalCode"
]

Notice that with version 0.3.0, you get the values instead (try here):

[
  "naist street",
  "Nara",
  "630-0192"
]

I would consider this a bug.