Skip to content

Commit 9ea4bc0

Browse files
committed
[jep-017] Root Reference.
1 parent 4845bdd commit 9ea4bc0

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

jep-017-root-reference.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Root Reference
2+
3+
|||
4+
|---|---
5+
| **JEP** | 17
6+
| **Author** | Maxime Labelle
7+
| **Status** | draft
8+
| **Created**| 25-02-2022
9+
10+
## Abstract
11+
12+
This document proposes grammar modifications to JMESPath
13+
to support referring to the original input JSON document
14+
inside an expression.
15+
16+
## Motivation
17+
18+
As a JMESPath expression is being evaluated, the current scope changes.
19+
Given a simple sub expression such as `foo.bar`, first the `foo`
20+
expression is evaluated with the starting input JSON document, and the
21+
result of that expression is then used as the current scope when the
22+
`bar` element is evaluated.
23+
24+
Once we’ve drilled down to a specific scope, there is no way, in the
25+
context of the currently evaluated expression, to refer to any
26+
elements outside of that element.
27+
28+
A common request when querying JSON objects is the ability to refer to
29+
the input JSON document.
30+
31+
For example, suppose we had this data:
32+
33+
```
34+
{
35+
"first_choice": "WA",
36+
"states": [
37+
{"name": "WA", "cities": ["Seattle", "Bellevue", "Olympia"]},
38+
{"name": "CA", "cities": ["Los Angeles", "San Francisco"]},
39+
{"name": "NY", "cities": ["New York City", "Albany"]}
40+
]
41+
}
42+
```
43+
44+
Let’s say we wanted to get the list of cities of the state corresponding
45+
to our `first_choice` key. We’ll make the assumption that the state
46+
names are unique in the `states` list. This is currently not possible
47+
with JMESPath. In this example we can hard code the state `"WA"`:
48+
49+
```
50+
states[?name==`"WA"`].cities
51+
```
52+
53+
but it is not possible to base this on a value of `first_choice`, which comes from the parent element.
54+
This JEP proposes a solution that makes this possible in JMESPath.
55+
56+
## Specification
57+
58+
The grammar will support a new token `$` that refers to the root of the original input JSON document.
59+
60+
The `$` token is inspired by the [JSONPath](https://goessner.net/articles/JsonPath/) specification which has a token with the same name.
61+
62+
The `$` token is also inspired by the [XPath](https://www.w3.org/TR/1999/REC-xpath-19991116) specification, where the `/` token designates the root of the original XML document.
63+
64+
This JEP introduces the following productions:
65+
66+
```
67+
root-node = "$"
68+
```
69+
70+
The `expression` production will also be updated like so:
71+
72+
```
73+
expression =/ root-node
74+
```
75+
76+
### Motivating Example
77+
78+
With these changes defined, the expression in the “Motivation” section can be be written as:
79+
80+
```
81+
states[?name==$.first_choice].cities[]
82+
```
83+
84+
Which evalutes to `["Seattle", "Bellevue", "Olympia"]`.
85+
86+
## Rationale
87+
88+
This JEP standardizes a common request when querying JSON document as seen in [existing library](https://github.com/nanoporetech/jmespath-ts) implementations.
89+
90+
Some alternatives to this JEP are considered. Most notably, the [Lexical Scoping](./jep-011-let-function.md) proposal introduces a `let()` function that is a more general an flexible way to achieve the desired result. For instance, with the `let()` function, the expression in the “Motivation” section can be written as:
91+
92+
```
93+
let({root: @}, &states[?name==root.first_choice].cities[])
94+
```
95+
96+
Although the [Lexical Scoping](./jep-011-let-function.mdj) proposal covers this case in a more generic way,
97+
using the `$` root node reference provides a more succinct way to express a common case.

0 commit comments

Comments
 (0)