4 Funzionalità JSONPath

Panoramica

Questa sezione descrive le funzionalità JSONPath supportate nei passaggi di preprocessing dei valori degli item.

JSONPath è composto da segmenti separati da punti. Un segmento può assumere la forma di una semplice parola, che rappresenta il nome di un valore JSON, del carattere jolly (*) oppure di un costrutto più complesso racchiuso tra parentesi quadre. Il punto prima di un segmento tra parentesi quadre è facoltativo e può essere omesso.

Esempio JSONPath Descrizione
$.object.name Restituisce il contenuto di object.name.
$.object['name'] Restituisce il contenuto di object.name.
$.object.['name'] Restituisce il contenuto di object.name.
$["object"]['name'] Restituisce il contenuto di object.name.
$.['object'].["name"] Restituisce il contenuto di object.name.
$.object.history.length() Restituisce il numero di elementi dell'array object.history.
$[?(@.name == 'Object')].price.first() Restituisce il valore della proprietà price del primo oggetto denominato "Object".
$[?(@.name == 'Object')].history.first().length() Restituisce il numero di elementi dell'array history del primo oggetto denominato "Object".
$[?(@.price > 10)].length() Restituisce il numero di oggetti con un prezzo maggiore di 10.

Vedi anche: Escape dei caratteri speciali dai valori delle macro LLD in JSONPath.

Segmenti supportati

Segmento Descrizione
<name> Corrisponde a una proprietà dell'oggetto in base al nome.
* Corrisponde a tutte le proprietà dell'oggetto.
['<name>'] Corrisponde a una proprietà dell'oggetto in base al nome.
['<name>', '<name>', ...] Corrisponde a una proprietà dell'oggetto in base a uno qualsiasi dei nomi elencati.
[<index>] Corrisponde a un elemento dell'array in base all'indice.
[<number>, <number>, ...] Corrisponde a un elemento dell'array in base a uno qualsiasi degli indici elencati.
[*] Corrisponde a tutte le proprietà dell'oggetto o a tutti gli elementi dell'array.
[<start>:<end>] Corrisponde agli elementi dell'array in base all'intervallo definito:
<start> - il primo indice da corrispondere (incluso); se non specificato, corrisponde a tutti gli elementi dell'array dall'inizio; se negativo, specifica l'offset iniziale dalla fine dell'array;
<end> - l'ultimo indice da corrispondere (escluso); se non specificato, corrisponde a tutti gli elementi dell'array fino alla fine; se negativo, specifica l'offset iniziale dalla fine dell'array.
[?(<expression>)] Corrisponde a oggetti/elementi dell'array applicando un'espressione di filtro.

Per trovare un segmento corrispondente ignorandone l'ascendenza (segmento scollegato), deve essere preceduto da due punti (..). Ad esempio, $..name o $..['name'] restituiscono i valori di tutte le proprietà name.

I nomi degli elementi corrispondenti possono essere estratti aggiungendo un suffisso tilde (~) al JSONPath. Restituisce il nome dell'oggetto corrispondente o un indice in formato stringa dell'item dell'array corrispondente. Il formato di output segue le stesse regole delle altre query JSONPath: i risultati di un percorso definito vengono restituiti "così come sono", mentre i risultati di un percorso indefinito vengono restituiti in un array. Tuttavia, estrarre il nome di un elemento che corrisponde a un percorso definito ha un'utilità minima, poiché è già noto.

Espressione di filtro

L'espressione di filtro è un'espressione aritmetica in notazione infissa.

Operandi supportati:

Operando Descrizione
"<text>"
'<text>'
Costante di testo.

Esempio:
'value: \\'1\\''
"value: '1'"
<number> Costante numerica con supporto della notazione scientifica.

Esempio: 123
<jsonpath starting with $> Valore a cui si fa riferimento tramite il JSONPath dal nodo radice del documento di input; sono supportati solo percorsi definiti.

Esempio: $.object.name
<jsonpath starting with @> Valore a cui si fa riferimento tramite il JSONPath dall'oggetto/elemento corrente; sono supportati solo percorsi definiti.

Esempio: @.name

Operatori supportati:

Operatore Tipo Descrizione Risultato
- Binario Sottrazione Numero
+ Binario Addizione Numero
/ Binario Divisione Numero
* Binario Moltiplicazione Numero
== Binario Uguaglianza Booleano (1/0)
!= Binario Disuguaglianza Booleano (1/0)
< Binario Minore di Booleano (1/0)
<= Binario Minore o uguale a Booleano (1/0)
> Binario Maggiore di Booleano (1/0)
>= Binario Maggiore o uguale a Booleano (1/0)
=~ Binario Corrisponde all'espressione regolare Booleano (1/0)
! Unario NOT booleano Booleano (1/0)
|| Binario OR booleano Booleano (1/0)
&& Binario AND booleano Booleano (1/0)

Funzioni

Le funzioni possono essere utilizzate alla fine di JSONPath. È possibile concatenare più funzioni se la funzione precedente restituisce un valore accettato dalla funzione successiva.

Funzioni supportate:

Funzione Descrizione Input Output
avg Valore medio dei numeri in un array di input Array di numeri Numero
min Valore minimo dei numeri in un array di input Array di numeri Numero
max Valore massimo dei numeri in un array di input Array di numeri Numero
sum Somma dei numeri in un array di input Array di numeri Numero
length Numero di elementi in un array di input Array Numero
first Il primo elemento di un array Array Un costrutto JSON (oggetto, array, valore) in base al contenuto dell'array di input

Le funzioni aggregate di JSONPath accettano valori numerici tra virgolette. Questi valori vengono convertiti automaticamente da stringhe a tipi numerici quando è necessaria un'aggregazione. Un input incompatibile farà sì che la funzione generi un errore.

Valore di output

I JSONPath possono essere suddivisi in percorsi definiti e indefiniti. Un percorso definito può restituire solo null oppure una singola corrispondenza. Un percorso indefinito può restituire più corrispondenze: JSONPath con elenchi di nomi/indici separati, multipli, slice di array o segmenti di espressione. Tuttavia, quando viene utilizzata una funzione, il JSONPath diventa definito, poiché le funzioni producono sempre un singolo valore.

Un percorso definito restituisce l'oggetto/l'array/il valore a cui fa riferimento. Al contrario, un percorso indefinito restituisce un array degli oggetti/array/valori corrispondenti.

L'ordine delle proprietà nei risultati delle query JSONPath potrebbe non corrispondere all'ordine originale delle proprietà nel JSON a causa dei metodi di ottimizzazione interni. Ad esempio, il JSONPath $.books[1]["author", "title"] può restituire ["title", "author"]. Se è essenziale preservare l'ordine originale delle proprietà, è opportuno considerare metodi alternativi di elaborazione successiva alla query.

Regole di formattazione del percorso

Gli spazi bianchi (spazio, carattere di tabulazione) possono essere utilizzati nei segmenti con notazione tra parentesi quadre e nelle espressioni, ad esempio: $[ 'a' ][ 0 ][ ?( $.b == 'c' ) ][ : -1 ].first( ).

Le stringhe devono essere racchiuse tra apici singoli (') o doppi ("). All'interno delle stringhe, gli apici singoli o doppi (a seconda di quelli usati per racchiuderle) e le barre rovesciate (\) vengono preceduti dal carattere barra rovesciata (\).

Esempio

{
  "books": [
    {
      "category": "riferimento",
      "author": "Nigel Rees",
      "title": "Detti del secolo",
      "price": 8.95,
      "id": 1
    },
    {
      "category": "narrativa",
      "author": "Evelyn Waugh",
      "title": "Spada d'onore",
      "price": 12.99,
      "id": 2
    },
    {
      "category": "narrativa",
      "author": "Herman Melville",
      "title": "Moby Dick",
      "isbn": "0-553-21311-3",
      "price": 8.99,
      "id": 3
    },
    {
      "category": "narrativa",
      "author": "J. R. R. Tolkien",
      "title": "Il Signore degli Anelli",
      "isbn": "0-395-19395-8",
      "price": 22.99,
      "id": 4
    }
  ],
  "services": {
    "delivery": {
      "servicegroup": 1000,
      "description": "Consegna il giorno successivo nella città locale",
      "active": true,
      "price": 5
    },
    "bookbinding": {
      "servicegroup": 1001,
      "description": "Stampa e assemblaggio del libro in formato A5",
      "active": true,
      "price": 154.99
    },
    "restoration": {
      "servicegroup": 1002,
      "description": "Vari metodi di restauro",
      "active": false,
      "methods": [
        {
          "description": "Pulizia chimica",
          "price": 46
        },
        {
          "description": "Pressatura di pagine danneggiate dall'umidità",
          "price": 24.5
        },
        {
          "description": "Rilegatura di un libro strappato",
          "price": 99.49
        }
      ]
    }
  },
  "filters": {
    "price": 10,
    "category": "narrativa",
    "no filters": "nessun \"filtro\""
  },
  "closed message": "Il negozio è chiuso",
  "tags": [
    "a",
    "b",
    "c",
    "d",
    "e"
  ]
}
JSONPath Type Result
$.filters.price definite 10
$.filters.category definite narrativa
$.filters['no filters'] definite nessun "filtro"
$.filters definite {
"price": 10,
"category": "narrativa",
"no filters": "nessun \"filtro\""
}
$.books[1].title definite Spada d'onore
$.books[-1].author definite J. R. R. Tolkien
$.books.length() definite 4
$.tags[:] indefinite ["a", "b", "c", "d", "e" ]
$.tags[2:] indefinite ["c", "d", "e" ]
$.tags[:3] indefinite ["a", "b", "c"]
$.tags[1:4] indefinite ["b", "c", "d"]
$.tags[-2:] indefinite ["d", "e"]
$.tags[:-3] indefinite ["a", "b"]
$.tags[:-3].length() definite 2
$.books[0, 2].title indefinite ["Moby Dick", "Detti del secolo"]
$.books[1]['author', "title"] indefinite ["Spada d'onore", "Evelyn Waugh"]
$..id indefinite [1, 2, 3, 4]
$.services..price indefinite [154.99, 5, 46, 24.5, 99.49]
$.books[?(@.id == 4 - 0.4 * 5)].title indefinite ["Spada d'onore"]

Nota: Questa query mostra che nelle query possono essere usate operazioni aritmetiche; può essere semplificata in $.books[?(@.id == 2)].title
$.books[?(@.id == 2 \|\| @.id == 4)].title indefinite ["Spada d'onore", "Il Signore degli Anelli"]
$.books[?(!(@.id == 2))].title indefinite ["Detti del secolo", "Moby Dick", "Il Signore degli Anelli"]
$.books[?(@.id != 2)].title indefinite ["Detti del secolo", "Moby Dick", "Il Signore degli Anelli"]
$.books[?(@.title =~ " of ")].title indefinite ["Detti del secolo", "Spada d'onore", "Il Signore degli Anelli"]
$.books[?(@.price > 12.99)].title indefinite ["Il Signore degli Anelli"]
$.books[?(@.author > "Herman Melville")].title indefinite ["Detti del secolo", "Il Signore degli Anelli"]
$.books[?(@.price > $.filters.price)].title indefinite ["Spada d'onore", "Il Signore degli Anelli"]
$.books[?(@.category == $.filters.category)].title indefinite ["Spada d'onore","Moby Dick","Il Signore degli Anelli"]
$.books[?(@.category == "fiction" && @.price < 10)].title indefinite ["Moby Dick"]
$..[?(@.id)] indefinite [
{
"price": 8.95,
"id": 1,
"category": "riferimento",
"author": "Nigel Rees",
"title": "Detti del secolo"
},
{
"price": 12.99,
"id": 2,
"category": "narrativa",
"author": "Evelyn Waugh",
"title": "Spada d'onore"
},
{
"price": 8.99,
"id": 3,
"category": "narrativa",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3"
},
{
"price": 22.99,
"id": 4,
"category": "narrativa",
"author": "J. R. R. Tolkien",
"title": "Il Signore degli Anelli",
"isbn": "0-395-19395-8"
}
]
$.services..[?(@.price > 50)].description indefinite ["Stampa e assemblaggio del libro in formato A5", "Rilegatura di un libro strappato"]
$..id.length() definite 4
$.books[?(@.id == 2)].title.first() definite Spada d'onore
$..tags.first().length() definite 5

Nota: $..tags è un percorso indefinito, quindi restituisce un array di elementi corrispondenti, cioè [["a", "b", "c", "d", "e" ]]; first() restituisce il primo elemento, cioè ["a", "b", "c", "d", "e"]; length() calcola la lunghezza dell'elemento, cioè 5.
$.books[*].price.min() definite 8.95
$..price.max() definite 154.99
$.books[?(@.category == "fiction")].price.avg() definite 14.99
$.books[?(@.category == $.filters.xyz)].title indefinite Nota: Una query senza corrispondenze restituisce NULL per i percorsi definiti e indefiniti.
$.services[?(@.active=="true")].servicegroup indefinite [1001,1000]

Nota: Nelle comparazioni con valori booleani devono essere usate costanti testuali.
$.services[?(@.active=="false")].servicegroup indefinite [1002]

Nota: Nelle comparazioni con valori booleani devono essere usate costanti testuali.
$.services[?(@.servicegroup=="1002")]~.first() definite restoration