Skip to content

Commit 2f8bbec

Browse files
mw75mattbaileyuk
authored andcommitted
Update tutorial.md
Fixed headline markdown for better reading.
1 parent ad6a56e commit 2f8bbec

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed

tutorial.md

+32-32
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
# JSONata
22
JSON query and transformation language
33

4-
###Introduction
4+
### Introduction
55
The primary purpose of this language is to extract values from JSON documents, with the
66
additional capabilities to combine these values using a set of basic functions
77
and operators, and also the ability to format the output into any arbitrary JSON structure.
88

9-
###Basic Selection
9+
### Basic Selection
1010
To support the extraction of values from a JSON structure, a location path syntax is defined.
1111
In common with XPath, this will select all possible values in the document that match the
1212
specified location path. The two structural constructs of JSON are objects and arrays.
1313

14-
####Navigating JSON Objects
14+
#### Navigating JSON Objects
1515
A JSON object is an associative array (a.k.a map or hash).
1616
The location path syntax to navigate into an arbitrarily deeply nested structure of
1717
JSON objects comprises the field names separated by dot '.' delimiters.
@@ -84,7 +84,7 @@ The following expressions yield the following results when applied to this JSON
8484

8585

8686

87-
####Navigating JSON Arrays
87+
#### Navigating JSON Arrays
8888
JSON arrays are used when an ordered collection of values is required.
8989
Each value in the array is associated with an index (position) rather than a name, so in order to address
9090
individual values in an array, extra syntax is required to specify the index.
@@ -113,7 +113,7 @@ array will be queried for selection.
113113
| `Phone.number[0]`| `[ "0203 544 1234", "01962 001234", "01962 001235", "077 7700 1234" ]`| Might expect it to just return the first number, <br>but it returns the first number of each of the items selected by `Phone`
114114
| `(Phone.number)[0]`| `"0203 544 1234"`| Applies the index to the array returned by `Phone.number`. One use of [parentheses](#parenthesized-expressions-and-blocks).
115115

116-
#####Top level arrays, nested arrays and array flattening
116+
##### Top level arrays, nested arrays and array flattening
117117
Consider the JSON document:
118118
```
119119
[
@@ -133,24 +133,24 @@ the document as follows:
133133
| `$[0].ref[0]` | `1` | returns element on first position of the internal array
134134
| `$.ref` | `[ 1, 2, 3, 4 ]` | Despite the structure of the nested array, the resultant selection<br>is flattened into a single flat array. The original nested structure<br>of the input arrays is lost. See [Array constructors](#array-constructors) for how to<br>maintain the original structure in the results.
135135

136-
###Complex selection
136+
### Complex selection
137137

138-
####Wildcards
138+
#### Wildcards
139139
Use of `*` instead of field name to select all fields in an object
140140

141141
Expression | Output | Comments|
142142
| ---------- | ------ |----|
143143
| `Address.*` | `[ "Hursley Park", "Winchester", "SO21 2JN" ]` | Select the values of all the fields of `Address`
144144
| `*.Postcode` | `"SO21 2JN"` | Select the `Postcode` value of any child object
145145

146-
####Navigate arbitrary depths
146+
#### Navigate arbitrary depths
147147
Descendant wildcard `**` instead of `*` will traverse all descendants (multi-level wildcard).
148148

149149
Expression | Output | Comments|
150150
| ---------- | ------ |----|
151151
| `**.Postcode` | `[ "SO21 2JN", "E1 6RF" ]` | Select all `Postcode` values, regardless of how deeply nested they are in the structure
152152

153-
####Predicates
153+
#### Predicates
154154
At any step in a location path, the selected items can be filtered using a predicate - [expr]
155155
where expr evaluates to a Boolean value. Each item in the selection is tested against
156156
the expression, if it evaluates to true, then the item is kept; if false, it is removed
@@ -165,7 +165,7 @@ Expression | Output | Comments|
165165
| `Phone[type='mobile'].number` | `"077 7700 1234"` | Select the mobile phone number
166166
| `Phone[type='office'].number` | `[ "01962 001234", "01962 001235" ]` | Select the office phone numbers - there are two of them!
167167

168-
####Singleton array and value equivalence
168+
#### Singleton array and value equivalence
169169
Within a JSONata expression or subexpression, any value (which is not itself an array) and an array
170170
containing just that value are deemed to be equivalent. This allows the language to be composable
171171
such that location paths that extract a single value from and object and location paths
@@ -196,9 +196,9 @@ to always return an array as follows:
196196

197197
Note that the `[]` can be placed either side of the predicates and on any step in the path expression
198198

199-
###Combining values
199+
### Combining values
200200

201-
####String expressions
201+
#### String expressions
202202
Path expressions that point to a string value will return that value.
203203
Strings can be combined using the concatenation operator '&'
204204

@@ -217,7 +217,7 @@ Consider the following JSON document:
217217
```
218218

219219

220-
####Numeric expressions
220+
#### Numeric expressions
221221
Path expressions that point to a number value will return that value.
222222
Numbers can be combined using the usual mathematical operators to produce
223223
a resulting number. Supported operators:
@@ -238,7 +238,7 @@ Expression | Output | Comments
238238
| `Numbers[2] % Numbers[5]` | 3.5 |Modulo operator|
239239

240240

241-
####Comparison expressions
241+
#### Comparison expressions
242242
Often used in predicates, for comparison of two values. Returns Boolean true or false
243243
Supported operators:
244244
- `=` equals
@@ -262,7 +262,7 @@ Expression | Output | Comments
262262
| `Numbers[2] >= Numbers[4]` | false |Greater than or equal|
263263
| `"01962 001234" in Phone.number` | true | Value is contained in|
264264

265-
####Boolean expressions
265+
#### Boolean expressions
266266
Used to combine Boolean results, often to support more sophisticated predicate expressions.
267267
Supported operators:
268268
- `and`
@@ -278,12 +278,12 @@ Expression | Output | Comments
278278
| `(Numbers[2] != 0) or (Numbers[5] = Numbers[1])` | true | `or` operator |
279279

280280

281-
###Specifying result structures
281+
### Specifying result structures
282282

283283
So far, we have discovered how to extract values from a JSON document, and how to manipulate the data using numeric, string and other operators.
284284
It is useful to be able to specify how this processed data is presented in the output.
285285

286-
####Array constructors
286+
#### Array constructors
287287
As previously observed, when a location path matches multiple values in the input document, these values are returned
288288
as an array. The values might be objects or arrays, and as such will have their own structure,
289289
but the _matched values_ themselves are at the top level in the resultant array.
@@ -304,7 +304,7 @@ Expression | Output | Comments|
304304
| `[Address, Other.'Alternative.Address'].City` | `[ "Winchester", "London" ]` | Selects the `City` value of both <br>`Address` and `Alternative.Address` objects
305305

306306

307-
####Object constructors
307+
#### Object constructors
308308
In a similar manner to the way arrays can be constructed, JSON objects can also be constructed in the output.
309309
At any point in a location path where a field reference is expected, a pair of braces `{}` containing key/value
310310
pairs separated by commas, with each key and value separated by a colon: `{key1: value2, key2:value2}`. The
@@ -322,7 +322,7 @@ Expression | Output | Comments|
322322
| `Phone{type: number}` | `{ "home": "0203 544 1234", "office": "01962 001235", "mobile": "077 7700 1234" }` | One of the `office` numbers was lost because it had a duplicate key
323323
| `Phone.{type: number}` | `[ { "home": "0203 544 1234" }, { "office": "01962 001234" }, { "office": "01962 001235" }, { "mobile": "077 7700 1234" } ]` | Produces an array of objects
324324

325-
####JSON literals
325+
#### JSON literals
326326
The array and object constructors use the standard JSON syntax for JSON arrays and JSON objects. In addition to this
327327
values of the other JSON data types can be entered into an expression using their native JSON syntax:
328328
- strings - `"hello world"`
@@ -336,19 +336,19 @@ This means that any valid JSON document is also a valid expression. This proper
336336
as a template for the desired output, and then replace parts of it with expressions to insert data into the output
337337
from the input document.
338338

339-
###Programming Constructs
339+
### Programming Constructs
340340
So far, we have introduced all the parts of the language that allow us to extract data from an input JSON document,
341341
combine the data using string and numeric operators, and format the structure of the output JSON document. What
342342
follows are the parts that turn this into a Turing complete, functional programming language.
343343

344-
####Conditional expressions
344+
#### Conditional expressions
345345
If/then/else constructs can be written using the ternary operator "? :".
346346
`predicate ? expr1 : expr2`
347347

348348
The expression `predicate` is evaluated. If its effective boolean value (see definition) is `true`
349349
then `expr1` is evaluated and returned, otherwise `expr2` is evaluated and returned.
350350

351-
####Parenthesized expressions and blocks
351+
#### Parenthesized expressions and blocks
352352
Used to override the operator precedence rules. E.g.
353353
- `(5 + 3) * 4`
354354

@@ -362,18 +362,18 @@ Used to support 'code blocks' - multiple expressions, separated by semicolons
362362
Each expression in the block is evaluated _in sequential order_; the result of the last expression
363363
is returned from the block.
364364

365-
####Variables
365+
#### Variables
366366
Any name that starts with a dollar '$' is a variable. A variable is a named reference to a value.
367367
The value can be one of any type in the language's type system (link).
368368

369-
#####Built-in variables
369+
##### Built-in variables
370370

371371
- `$` The variable with no name refers to the context value at any point in the input JSON hierarchy. Examples
372372
- `$$` The root of the input JSON. Only needed if you need to break out of the
373373
current context to temporarily navigate down a different path. E.g. for cross-referencing or joining data. Examples
374374
- Native (built-in) functions. See function library.
375375

376-
#####Variable assignment
376+
##### Variable assignment
377377
Values (of any type in the type system) can be assigned to variables
378378

379379
`$var_name := "value"`
@@ -391,22 +391,22 @@ Invoice.(
391391
```
392392
Returns Price multiplied by Quantity for the Product in the Invoice.
393393

394-
####Functions
394+
#### Functions
395395
The function is a first-class type, and can be stored in a variable just like any other
396396
data type. A library of built-in functions is provided (link) and assigned to variables
397397
in the global scope. For example, `$uppercase` contains a function which, when invoked
398398
with a string argument, `str`, will
399399
return a string with all the characters in `str` changed to uppercase.
400400

401-
#####Invoking a function
401+
##### Invoking a function
402402
A function is invoked by following its reference (or definition) by parentheses containing
403403
a comma delimited sequence of arguments. Examples:
404404

405405
- `$uppercase("Hello")` returns the string "HELLO".
406406
- `$substring("hello world", 0, 5)` returns the string "hello"
407407
- `$sum([1,2,3])` returns the number 6
408408

409-
#####Defining a function
409+
##### Defining a function
410410
Anonymous (lambda) functions can be defined using the following syntax:
411411

412412
`function($l, $w, $h){ $l * $w * $h }`
@@ -424,7 +424,7 @@ The function can also be assigned to a variable for future use (within the block
424424
)
425425
```
426426

427-
#####Recursive functions
427+
##### Recursive functions
428428
Functions that have been assigned to variables can invoke themselves using
429429
that variable reference. This allows recursive functions to be defined. Eg.
430430

@@ -440,7 +440,7 @@ Note that it is actually possible to write a recursive function using purely ano
440440
which might be an interesting [diversion](#advanced-stuff) for those interested in functional programming.
441441

442442

443-
#####Higher order functions
443+
##### Higher order functions
444444
A function, being a first-class data type, can be passed as a parameter to
445445
another function, or returned from a function. Functions that process other functions
446446
are known as higher order functions. Consider the following example:
@@ -464,7 +464,7 @@ invoked yet, but rather assigned to the variable `add6`.
464464
- Finally the function in `$add6` is invoked with the argument 7, resulting in 3 being added to it twice.
465465
It returns 13.
466466

467-
#####Functions are closures
467+
##### Functions are closures
468468
When a lambda function is defined, the evaluation engine takes a snapshot of the environment and stores it with the
469469
function body definition. The environment comprises the context item (i.e. the current value in the location path)
470470
together with the current in-scope variable bindings. When the lambda function is later invoked, it is done so in that
@@ -495,7 +495,7 @@ The expression produces the following result:
495495
}
496496
```
497497

498-
#####Advanced stuff
498+
##### Advanced stuff
499499
There is no need to read this section - it will do nothing for your sanity or ability to manipulate JSON data.
500500

501501
Earlier we learned how to write a recursive function to calculate the factorial of a number and hinted that this

0 commit comments

Comments
 (0)