0
# JSONPath Expressions
1
2
Core Abstract Syntax Tree (AST) classes representing different JSONPath operations. These classes form the building blocks of parsed JSONPath expressions and can be used to construct expressions programmatically.
3
4
## Capabilities
5
6
### Base JSONPath Class
7
8
Abstract base class defining the interface for all JSONPath expression types.
9
10
```python { .api }
11
class JSONPath:
12
"""
13
Base class for JSONPath abstract syntax tree nodes.
14
"""
15
16
def find(self, data):
17
"""
18
Find all matches for this JSONPath in the given data.
19
20
Parameters:
21
- data: Input data to search (dict, list, or DatumInContext)
22
23
Returns:
24
list[DatumInContext]: List of matching data with context
25
"""
26
27
def update(self, data, val):
28
"""
29
Update data at the path specified by this JSONPath.
30
31
Parameters:
32
- data: Input data to update
33
- val: New value to set at the path
34
35
Returns:
36
Updated data structure
37
"""
38
39
def child(self, child):
40
"""
41
Create a child path with canonicalization.
42
43
Parameters:
44
- child: JSONPath object to use as child
45
46
Returns:
47
JSONPath: Composed path expression
48
"""
49
50
def make_datum(self, value):
51
"""
52
Create a DatumInContext from a value.
53
54
Parameters:
55
- value: Value to wrap (or existing DatumInContext)
56
57
Returns:
58
DatumInContext: Wrapped value with path context
59
"""
60
```
61
62
### Root Expression
63
64
Represents the root object reference (`$` in JSONPath syntax).
65
66
```python { .api }
67
class Root(JSONPath):
68
"""
69
JSONPath referring to the root object. Concrete syntax: '$'
70
"""
71
72
def find(self, data):
73
"""
74
Returns the root datum.
75
76
Parameters:
77
- data: Input data
78
79
Returns:
80
list[DatumInContext]: Single-element list with root datum
81
"""
82
83
def update(self, data, val):
84
"""
85
Replace entire data with new value.
86
87
Parameters:
88
- data: Original data
89
- val: Replacement value
90
91
Returns:
92
val: The replacement value
93
"""
94
```
95
96
### Current Object Expression
97
98
Represents the current datum reference (`@` or `` `this` `` in JSONPath syntax).
99
100
```python { .api }
101
class This(JSONPath):
102
"""
103
JSONPath referring to the current datum. Concrete syntax: '@' or `this`
104
"""
105
106
def find(self, datum):
107
"""
108
Returns the current datum wrapped in context.
109
110
Parameters:
111
- datum: Current datum
112
113
Returns:
114
list[DatumInContext]: Single-element list with wrapped datum
115
"""
116
117
def update(self, data, val):
118
"""
119
Replace data with new value.
120
121
Parameters:
122
- data: Original data
123
- val: Replacement value
124
125
Returns:
126
val: The replacement value
127
"""
128
```
129
130
### Field Access Expression
131
132
Represents field access operations for objects.
133
134
```python { .api }
135
class Fields(JSONPath):
136
"""
137
JSONPath for field access. Supports single fields, multiple fields, and wildcards.
138
"""
139
140
def __init__(self, *fields):
141
"""
142
Initialize field access expression.
143
144
Parameters:
145
- fields: Variable number of field names (str)
146
Use '*' for all fields
147
"""
148
149
def find(self, datum):
150
"""
151
Find matching fields in the datum.
152
153
Parameters:
154
- datum: Input datum (typically dict-like)
155
156
Returns:
157
list[DatumInContext]: Matching field values with context
158
"""
159
160
def get_field_datum(self, datum, field):
161
"""
162
Get a specific field from datum.
163
164
Parameters:
165
- datum: DatumInContext containing dict-like value
166
- field: str, field name to access
167
168
Returns:
169
DatumInContext or None: Field value with context, or None if not found
170
"""
171
172
def reified_fields(self, datum):
173
"""
174
Expand '*' wildcards to actual field names.
175
176
Parameters:
177
- datum: DatumInContext containing dict-like value
178
179
Returns:
180
tuple: Actual field names to access
181
"""
182
183
def update(self, data, val):
184
"""
185
Update data by setting field values.
186
187
Parameters:
188
- data: Input data structure
189
- val: New value to set at field paths
190
191
Returns:
192
Updated data structure with field values set
193
"""
194
```
195
196
### Array Index Expression
197
198
Represents array index access operations.
199
200
```python { .api }
201
class Index(JSONPath):
202
"""
203
JSONPath for array index access. Concrete syntax: [n]
204
"""
205
206
def __init__(self, index):
207
"""
208
Initialize index access expression.
209
210
Parameters:
211
- index: int, array index to access
212
"""
213
214
def find(self, datum):
215
"""
216
Find element at the specified index.
217
218
Parameters:
219
- datum: Input datum (typically list-like)
220
221
Returns:
222
list[DatumInContext]: Single element if index exists, empty list otherwise
223
"""
224
225
def update(self, data, val):
226
"""
227
Update data by setting value at the specified index.
228
229
Parameters:
230
- data: Input data structure (typically list-like)
231
- val: New value to set at the index
232
233
Returns:
234
Updated data structure with value set at index
235
"""
236
```
237
238
### Array Slice Expression
239
240
Represents array slice operations with optional start, end, and step parameters.
241
242
```python { .api }
243
class Slice(JSONPath):
244
"""
245
JSONPath for array slice access. Concrete syntax: [start:end:step] or [*]
246
Includes type coercion for non-array data.
247
"""
248
249
def __init__(self, start=None, end=None, step=None):
250
"""
251
Initialize slice expression.
252
253
Parameters:
254
- start: int or None, slice start index
255
- end: int or None, slice end index
256
- step: int or None, slice step size
257
258
Note: If all parameters are None, acts as wildcard [*]
259
"""
260
261
def find(self, datum):
262
"""
263
Find elements in the specified slice.
264
Coerces non-list data to single-element lists.
265
266
Parameters:
267
- datum: Input datum
268
269
Returns:
270
list[DatumInContext]: Slice elements with context
271
"""
272
273
def update(self, data, val):
274
"""
275
Update data by setting values in the specified slice.
276
277
Parameters:
278
- data: Input data structure
279
- val: New value to set in slice positions
280
281
Returns:
282
Updated data structure with slice values set
283
"""
284
```
285
286
### Child Composition Expression
287
288
Represents path composition operations (left.right).
289
290
```python { .api }
291
class Child(JSONPath):
292
"""
293
JSONPath that first matches the left, then the right.
294
Concrete syntax: <left>.<right>
295
"""
296
297
def __init__(self, left, right):
298
"""
299
Initialize child composition.
300
301
Parameters:
302
- left: JSONPath, first expression to match
303
- right: JSONPath, second expression to match from left results
304
"""
305
306
def find(self, datum):
307
"""
308
Find right matches from all left matches.
309
310
Parameters:
311
- datum: Input datum
312
313
Returns:
314
list[DatumInContext]: All right matches from left results
315
"""
316
```
317
318
### Parent Access Expression
319
320
Represents parent node access (`` `parent` `` named operator).
321
322
```python { .api }
323
class Parent(JSONPath):
324
"""
325
JSONPath that matches the parent node of the current match.
326
Available via named operator `parent`.
327
"""
328
329
def find(self, datum):
330
"""
331
Find the parent context of the datum.
332
333
Parameters:
334
- datum: DatumInContext with parent context
335
336
Returns:
337
list[DatumInContext]: Parent context
338
339
Note: Will crash if no parent exists
340
"""
341
```
342
343
### Descendant Query Expression
344
345
Represents descendant access operations (left..right).
346
347
```python { .api }
348
class Descendants(JSONPath):
349
"""
350
JSONPath that matches descendants. Concrete syntax: <left>..<right>
351
Finds all nodes matching right that descend from left matches.
352
"""
353
354
def __init__(self, left, right):
355
"""
356
Initialize descendant query.
357
358
Parameters:
359
- left: JSONPath, ancestor expression
360
- right: JSONPath, descendant expression to match
361
"""
362
363
def find(self, datum):
364
"""
365
Find all right matches that descend from left matches.
366
Recursively searches through objects and arrays.
367
368
Parameters:
369
- datum: Input datum
370
371
Returns:
372
list[DatumInContext]: All descendant matches
373
"""
374
375
def is_singular(self):
376
"""
377
Check if this expression returns a single result.
378
379
Returns:
380
bool: Always False for descendant expressions
381
"""
382
```
383
384
### Filtering Expression
385
386
Represents filtering operations (left where right).
387
388
```python { .api }
389
class Where(JSONPath):
390
"""
391
JSONPath for filtering. Concrete syntax: <left> where <right>
392
Filters left matches to only those that have right matches.
393
"""
394
395
def __init__(self, left, right):
396
"""
397
Initialize filter expression.
398
399
Parameters:
400
- left: JSONPath, expression to filter
401
- right: JSONPath, filter condition expression
402
"""
403
404
def find(self, data):
405
"""
406
Filter left matches that have right matches.
407
408
Parameters:
409
- data: Input data
410
411
Returns:
412
list[DatumInContext]: Filtered left matches
413
"""
414
```
415
416
### Union Expression
417
418
Represents union operations (left|right).
419
420
```python { .api }
421
class Union(JSONPath):
422
"""
423
JSONPath that returns union of results. Concrete syntax: <left>|<right>
424
"""
425
426
def __init__(self, left, right):
427
"""
428
Initialize union expression.
429
430
Parameters:
431
- left: JSONPath, first expression
432
- right: JSONPath, second expression
433
"""
434
435
def find(self, data):
436
"""
437
Return combined results from both expressions.
438
439
Parameters:
440
- data: Input data
441
442
Returns:
443
list[DatumInContext]: Combined results from left and right
444
"""
445
446
def is_singular(self):
447
"""
448
Check if this expression returns a single result.
449
450
Returns:
451
bool: Always False for union expressions
452
"""
453
```
454
455
### Intersection Expression (Not Implemented)
456
457
Placeholder for intersection operations (left&right).
458
459
```python { .api }
460
class Intersect(JSONPath):
461
"""
462
JSONPath for intersection. Concrete syntax: <left>&<right>
463
WARNING: Not implemented - find() raises NotImplementedError
464
"""
465
466
def __init__(self, left, right):
467
"""
468
Initialize intersection expression.
469
470
Parameters:
471
- left: JSONPath, first expression
472
- right: JSONPath, second expression
473
"""
474
475
def find(self, data):
476
"""
477
Find intersection of left and right matches.
478
479
Parameters:
480
- data: Input data
481
482
Raises:
483
NotImplementedError: Intersection is not yet implemented
484
"""
485
486
def is_singular(self):
487
"""
488
Check if this expression returns a single result.
489
490
Returns:
491
bool: Always False for intersection expressions
492
"""
493
```
494
495
## Programmatic Construction
496
497
You can build JSONPath expressions directly without parsing:
498
499
```python
500
from jsonpath_rw.jsonpath import Root, Fields, Slice, Index
501
502
# Equivalent to parse('$.foo[*].bar')
503
expr = Root().child(Fields('foo')).child(Slice()).child(Fields('bar'))
504
505
# Equivalent to parse('users[0].name')
506
expr = Fields('users').child(Index(0)).child(Fields('name'))
507
508
# Multiple fields: parse('name,email,age')
509
expr = Fields('name', 'email', 'age')
510
```