ietf-wg-jsonpath / draft-ietf-jsonpath-base

Development of a JSONPath internet draft
https://ietf-wg-jsonpath.github.io/draft-ietf-jsonpath-base/
Other
59 stars 20 forks source link

Do we have a way to query and return the root object? #390

Open gregsdennis opened 1 year ago

gregsdennis commented 1 year ago

For JSON Schema, I'm exploring Spectral which uses JSON Path to identify nodes that need rules applied to them.

I'm having trouble isolating the root object when type is object.

For example:

{
  "type": "object",
  "properties": {
    "bar": {
      "type": "object",
      "minimum": 5
    }
  },
  "minimum": 5
}

For this data, the path $..[?(@.type=='object')] returns only the node at /properties/bar. However, I want to also return the root object since it also contains type: object.

I don't think we have support for this, and it seems pretty crucial.

goessner commented 1 year ago

It is a well known insufficiency of JSONPath, not being able to address root level member names / element indices by filters. A way out of this would be ...

$..[?index(@) == 'type' && @ == 'object']

We are able to select the parent of identified members / elements via filters by nesting. But this does not work at root level.

But ... the resulting normalized pathes always contain the required information.

gregsdennis commented 1 year ago

I'm still not sure that works as the problem is the descendant segment .. which only selects descendants, not the node itself.

goessner commented 1 year ago

[###] works on children and ..[###] on descendants. Why should the node itself be in the result list (I know, XPath meanwhile has both: descendant and descendant_or_self).

By above query we will get the nodelist (normalized pathes)

[
  "$['type']",
  "$['properties']['bar']['type']"
]

which contains everything you want to know.

gregsdennis commented 1 year ago

which contains everything you want to know.

The problem is that I'm just giving the path to Spectral. Spectral may have all the info it needs (maybe, depending on the implementation), but I have no way of instructing it to do anything with that info.

This is the same problem expressed in #156.

cabo commented 1 year ago

I think we need to start collecting the extensions we would like to have (I don't think we want to have this in the base standard, as this is not currently a widely deployed feature). Obviously, this needs to be an extended form of segment. Let's call that ...[], i.e. a "descendants-or-self" segment. $...[?(@.type=='object')] would be the filter selection you are looking for. (Of course, this cannot be solved with an existing extension point because we don't "get at the root" with what we have.)

glyn commented 1 year ago

I agree this feature shouldn't go in the base because it doesn't fit into the charter. So I propose we close the issue with the label revisit-after-base-done.

danielaparker commented 1 year ago

I agree this feature shouldn't go in the base because it doesn't fit into the charter.

That would apply to functions as per the draft as well.

cabo commented 1 year ago

I agree this feature shouldn't go in the base because it doesn't fit into the charter.

That would apply to functions as per the draft as well.

One might think so. But then functions were our way to provide an extension point, which is crucial for the further development of the protocol. Also, length, match/search are widely provided, if not exactly in that syntax/semantics (but there also is no consensus among implementations that would have argued for some other form).

So, back to root access: Is this something for which we can derive a consensus between currently available implementations?

danielaparker commented 1 year ago

I agree this feature shouldn't go in the base because it doesn't fit into the charter.

That would apply to functions as per the draft as well.

One might think so. But then functions were our way to provide an extension point, which is crucial for the further development of the protocol.

A difficulty though is that support for functions is a feature in what is probably the most widely deployed implementation of all, Jayway (and Oracle) JSONPath, but in a way that is incompatible with the committee's proposal.

cabo commented 1 year ago

Jayway "functions" are an entirely different thing from the functions we have in filter expressions.

I don't think something like Jayway "functions" (which really are segments in our current parlance, except that they don't select, but compute) would be hard to add as an extension to JSONPath as defined now.

Unfortunately, we haven't come up with an extension point ready to accommodate these output transforming operations.

They are also orthogonal to what nodes selectors can reach, which is the subject of this Github issue.

goessner commented 1 year ago

If an extension point mechanism can be used to register analysis/mutator functions (average, deduplicate), that would be a good thing.

Those Jayway functions can (only) be used at the end of a path. So they are in fact post-processing functions, which are definitely not in our charter. But we could say someting like:

An implementation MAY use post-processing functions. If it does, they MUST follow the syntax and naming according to following rules.

cabo commented 1 year ago

I haven't heard anyone arguing that this needs to go into jsonpath-base. Closing this now, for revisit-after-base-done.

gregsdennis commented 1 year ago

I opened the issue highlighting Spectral as a pretty good use case, but okay.