or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdcontext.mdexpressions.mdindex.mdparsing.md

expressions.mddocs/

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

```