You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
By default, Python JSONPath extends the RFC 9535 specification with a few additional features and relaxed rules, making it more forgiving in everyday use. If you need strict compliance with RFC 9535, you can enable strict mode, which enforces the standard without these extensions. In this guide, we first outline the standard syntax (see the specification for the formal definition), and then describe the non-standard extensions and their semantics in detail.
3
+
By default, Python JSONPath extends the RFC 9535 specification with a few additional features and relaxed rules. If you need strict compliance with RFC 9535, you can enable strict mode, which enforces the standard without these extensions. In this guide, we first outline the standard syntax (see the specification for the formal definition), and then describe the non-standard extensions and their semantics in detail.
4
4
5
5
## JSONPath Terminology
6
6
@@ -241,7 +241,7 @@ $..price
241
241
242
242
## Non-standard selectors and identifiers
243
243
244
-
The selectors and identifiers described in this section are an extension to RFC 9535. They are enabled by default. See [#strict-mode] for details on how to use JSONPath following RFC 9535 strictly.
244
+
The selectors and identifiers described in this section are an extension to RFC 9535. They are enabled by default. See [#strict-mode] for details on how to use JSONPath without these extensions.
245
245
246
246
### Key selector
247
247
@@ -373,6 +373,8 @@ filter-selector = "~?" S logical-expr
373
373
374
374
### Singular query selector
375
375
376
+
**_New in version 2.0.0_**
377
+
376
378
The singular query selector consist of an embedded absolute singular query, the result of which is used as an object member name or array element index.
377
379
378
380
If the embedded query resolves to a string or int value, at most one object member value or array element value is selected. Otherwise the singular query selector selects nothing.
@@ -456,7 +458,7 @@ current-key-identifier = "#"
456
458
457
459
**_New in version 0.11.0_**
458
460
459
-
The pseudo root identifier (`^`) behaves like the standard root identifier (`$`), but conceptually wraps the target JSON document in a single-element array. This allows the root document itself to be addressed by selectors such as filters, which normally only apply to elements within arrays.
461
+
The pseudo root identifier (`^`) behaves like the standard root identifier (`$`), but conceptually wraps the target JSON document in a single-element array. This allows the root document itself to be conditionally selected by filters.
The filter context identifier (`_`) starts an embedded query, similar to the root identifier (`$`) and current node identifier (`@`), but targets JSON-like data passed as the `filter_context` argument to [`findall()`](api.md#jsonpath.JSONPath.findall) and [`finditer()`](api.md#jsonpath.JSONPath.finditer).
|`$.a[[email protected] == _.c]`|`{ "b": 42 }`|`$['a'][0]`| Comparison with extra context singular query |
485
517
486
518
## Non-standard operators
487
519
488
-
TODO
520
+
In addition to the operators described below, the standard _logical and_ operator (`&&`) is aliased as `and`, the standard _logical or_ operator (`||`) is aliased as `or`, and `null` is aliased as `nil` and `none`.
489
521
490
-
### Lists (`[1, 2, 10:20]`)
522
+
Also, `true`, `false`, `null` and their aliases can start with an upper case letter.
491
523
492
-
Select multiple indices, slices or properties using list notation (sometimes known as a "union" or "segment", we use "union" to mean something else).
524
+
### Membership operators
525
+
526
+
The membership operators test whether one value occurs within another.
527
+
528
+
An infix expression using `contains` evaluates to true if the right-hand side is a member of the left-hand side, and false otherwise.
529
+
530
+
- If the left-hand side is an object and the right-hand side is a string, the result is true if the object has a member with that name.
531
+
- If the left-hand side is an array, the result is true if any element of the array is equal to the right-hand side.
532
+
- For scalars (strings, numbers, booleans, null), `contains` always evaluates to false.
533
+
534
+
The `in` operator is equivalent to `contains` with operands reversed. This makes `contains` and `in` symmetric, so either form may be used depending on which reads more naturally in context.
535
+
536
+
A list literal is a comma separated list of JSONPath expression literals. List should appear on the left-hand side of `contains` or the right-hand side of `in`.
537
+
538
+
#### Syntax
493
539
494
-
```text
495
-
$..products.*.[title, price]
496
540
```
541
+
basic-expr = paren-expr /
542
+
comparison-expr /
543
+
membership-expr /
544
+
test-expr
545
+
546
+
membership-expr = comparable S membership-op S comparable
547
+
548
+
membership-operator = "contains" / "in"
549
+
550
+
membership-operand = literal /
551
+
singular-query / ; singular query value
552
+
function-expr / ; ValueType
553
+
list-literal
554
+
555
+
list-literal = "[" S literal *(S "," S literal) S "]"
Note that `|` and `&` are not allowed inside filter expressions.
515
597
516
-
## Notable differences
517
-
518
-
This is a list of things that you might find in other JSONPath implementation that we don't support (yet).
519
-
520
-
- We don't support extension functions of the form `selector.func()`.
521
-
- We always return a list of matches from `jsonpath.findall()`, never a scalar value.
522
-
- We do not support arithmetic in filter expression.
523
-
- We don't allow dotted array indices. An array index must be surrounded by square brackets.
524
-
- Python JSONPath is strictly read only. There are no update "selectors", but we do provide methods for converting `JSONPathMatch` instances to `JSONPointer`s, and a `JSONPatch` builder API for modifying JSON-like data structures using said pointers.
525
-
526
-
And this is a list of areas where we deviate from [RFC 9535](https://datatracker.ietf.org/doc/html/rfc9535). See [jsonpath-rfc9535](https://github.com/jg-rp/python-jsonpath-rfc9535) for an alternative implementation of JSONPath that does not deviate from RFC 9535.
527
-
528
-
- The root token (default `$`) is optional and paths starting with a dot (`.`) are OK. `.thing` is the same as `$.thing`, as is `thing`, `$[thing]` and `$["thing"]`.
529
-
- The built-in `match()` and `search()` filter functions use Python's standard library `re` module, which, at least, doesn't support Unicode properties. We might add an implementation of `match()` and `search()` using the third party [regex](https://pypi.org/project/regex/) package in the future.
530
-
- We don't check `match()` and `search()` regex arguments against RFC 9485. Any valid Python pattern is allowed.
531
-
- We don't require property names to be quoted inside a bracketed selection, unless the name contains reserved characters.
532
-
- We don't require the recursive descent segment to have a selector. `$..` is equivalent to `$..*`.
533
-
- We support explicit comparisons to `undefined` as well as implicit existence tests.
534
-
- Float literals without a fractional digit are OK or leading digit. `1.` is equivalent to `1.0`.
535
-
- We treat literals (such as `true` and `false`) as valid "basic" expressions. For example, `$[?true || false]`, without an existence test or comparison either side of logical _or_, does not raise a syntax error.
536
-
- By default, `and` is equivalent to `&&` and `or` is equivalent to `||`.
537
-
-`none` and `nil` are aliases for `null`.
538
-
-`null` (and its aliases), `true` and `false` can start with an upper or lower case letter.
539
-
- We don't treat some invalid `\u` escape sequences in quoted name selectors and string literals as an error. We match the behavior of the JSON decoder in Python's standard library, which is less strict than RFC 9535.
540
-
541
-
And this is a list of features that are uncommon or unique to Python JSONPath.
542
-
543
-
- We support membership operators `in` and `contains`, plus list/array literals.
544
-
-`|` is a union operator, where matches from two or more JSONPaths are combined. This is not part of the Python API, but built-in to the JSONPath syntax.
545
-
-`&` is an intersection operator, where we exclude matches that don't exist in both left and right paths. This is not part of the Python API, but built-in to the JSONPath syntax.
546
-
-`#` is the current key/property or index identifier when filtering a mapping or sequence.
547
-
-`_` is a filter context identifier. With usage similar to `$` and `@`, `_` exposes arbitrary data from the `filter_context` argument to `findall()` and `finditer()`.
548
-
-`~` is a "keys" or "properties" selector.
549
-
-`^` is a "fake root" identifier. It is equivalent to `$`, but wraps the target JSON document in a single-element array, so the root value can be conditionally selected with a filter selector.
550
-
-`=~` is the the regex match operator, matching a value to a JavaScript-style regex literal.
598
+
## Other differences
599
+
600
+
This is a list of areas where Python JSONPath is more relaxed than [RFC 9535](https://datatracker.ietf.org/doc/html/rfc9535).
601
+
602
+
- The root token (`$`) is optional and paths starting with a dot (`.`) are OK. `.thing` is the same as `$.thing`, as is `thing` and `$["thing"]`.
603
+
- Leading and trailing whitespace is OK.
604
+
- We support explicit comparisons to `undefined` (aka `missing`) as well as implicit existence tests.
0 commit comments