1. Introduction (Introduzione)
1. Introduction (Introduzione)
JSON [RFC8259] è un formato di rappresentazione diffuso per valori di dati strutturati. JSONPath definisce una sintassi di stringa per selezionare ed estrarre valori JSON all'interno di un dato valore JSON.
Rispetto a JSON Pointer [RFC6901], JSONPath non è inteso come sostituto ma come compagno più potente. Vedere Appendice C.
1.1. Terminology (Terminologia)
Le parole chiave "DEVE", "NON DEVE", "OBBLIGATORIO", "DOVREBBE", "NON DOVREBBE", "CONSIGLIATO", "NON CONSIGLIATO", "PUÒ" e "OPZIONALE" in questo documento devono essere interpretate come descritto in BCP 14 [RFC2119] [RFC8174] quando, e solo quando, compaiono interamente in maiuscolo, come mostrato qui.
Le regole grammaticali in questo documento devono essere interpretate come ABNF (Augmented Backus-Naur Form, forma Backus-Naur estesa), come descritto in [RFC5234]. I valori terminali ABNF in questo documento definiscono valori scalari Unicode piuttosto che la loro codifica UTF-8. Ad esempio, il segno PLACE OF INTEREST (U+2318) sarebbe definito in ABNF come %x2318.
Le funzioni sono indicate usando il nome della funzione seguito da una coppia di parentesi, come in fname().
Si applica la terminologia di [RFC8259] salvo quanto chiarito di seguito. I termini "primitive" (primitivo) e "structured" (strutturato) sono usati per raggruppare diversi tipi di valori come nella Sezione 1 di [RFC8259]. Gli oggetti e gli array JSON sono strutturati; tutti gli altri valori sono primitivi. Le definizioni di "object" (oggetto), "array", "number" (numero) e "string" (stringa) restano invariate. È importante che "object" e "array" in particolare non assumano un significato generico, come accadrebbe in un contesto di programmazione generale.
Si applica la terminologia di [RFC9485].
I termini aggiuntivi usati in questo documento sono definiti di seguito.
Value (valore): Come da [RFC8259], un elemento di dati conforme al modello dati generico di JSON, vale a dire dati primitivi (numeri, stringhe di testo e i valori speciali null, true e false) o dati strutturati (oggetti e array JSON). [RFC8259] si concentra sulla rappresentazione testuale dei valori JSON e non definisce completamente l'astrazione di valore qui assunta.
Member (membro): Una coppia nome/valore in un oggetto. (Un membro non è esso stesso un valore.)
Name (nome): Il nome (una stringa) in una coppia nome/valore che costituisce un membro. Ciò è usato anche in [RFC8259], ma quella specifica non lo definisce formalmente. È incluso qui per completezza.
Element (elemento): Un valore in un array JSON.
Index (indice): Un intero che identifica un elemento specifico in un array.
Query (interrogazione): Nome breve per un'espressione JSONPath.
Query Argument (argomento dell'interrogazione): Nome breve per il valore a cui viene applicata un'espressione JSONPath.
Location (posizione): La posizione di un valore nell'argomento dell'interrogazione. Può essere pensata come una sequenza di nomi e indici che navigano al valore attraverso gli oggetti e gli array nell'argomento dell'interrogazione, con la sequenza vuota che indica l'argomento dell'interrogazione stesso. Una posizione può essere rappresentata come Normalized Path (percorso normalizzato, definito sotto).
Node (nodo): La coppia di un valore insieme alla sua posizione nell'argomento dell'interrogazione.
Root Node (nodo radice): L'unico nodo il cui valore è l'intero argomento dell'interrogazione.
Root Node Identifier (identificatore del nodo radice): L'espressione $, che si riferisce al nodo radice dell'argomento dell'interrogazione.
Current Node Identifier (identificatore del nodo corrente): L'espressione @, che si riferisce al nodo corrente nel contesto della valutazione di un'espressione di filtro (descritta in seguito).
Children (figli) (di un nodo): Se il nodo è un array, i nodi dei suoi elementi; se il nodo è un oggetto, i nodi dei suoi valori di membro. Se il nodo non è né un array né un oggetto, non ha figli.
Descendants (discendenti) (di un nodo): I figli del nodo, insieme ai figli dei suoi figli, e così via ricorsivamente. Più formalmente, la relazione "descendants" tra nodi è la chiusura transitiva della relazione "children".
Depth (profondità) (di un nodo discendente in un valore): Il numero di antenati del nodo nel valore. Il nodo radice del valore ha profondità zero, i figli del nodo radice hanno profondità uno, i loro figli hanno profondità due, e così via.
Nodelist (lista di nodi): Una lista di nodi. Sebbene una nodelist possa essere rappresentata in JSON, ad esempio come array, questo documento non richiede né presuppone alcuna rappresentazione particolare.
Parameter (parametro): Parametro formale (di una funzione) che può ricevere un function argument (argomento di funzione, parametro attuale) in un'espressione di funzione.
Normalized Path (percorso normalizzato): Una forma di espressione JSONPath che identifica un nodo in un valore fornendo un'interrogazione che produce esattamente quel nodo. Ogni nodo in un argomento dell'interrogazione è identificato da esattamente un Normalized Path (si dice che il Normalized Path è "unique", unico, per quel nodo), e per essere un Normalized Path per un argomento dell'interrogazione specifico, il Normalized Path deve identificare esattamente un nodo. Ciò è simile, ma sintatticamente diverso, da un JSON Pointer [RFC6901]. Nota: questa definizione si basa sulla definizione sintattica nella Sezione 2.7; le espressioni JSONPath che identificano un nodo in un valore ma non sono conformi a quella sintassi non sono Normalized Paths.
Unicode Scalar Value (valore scalare Unicode): Qualsiasi punto di codice Unicode [UNICODE] tranne i punti di codice surrogate alto e basso (in altre parole, interi negli intervalli inclusivi in base 16, 0 a D7FF oppure E000 a 10FFFF). Le interrogazioni JSONPath sono sequenze di valori scalari Unicode.
Segment (segmento): Uno dei costrutti che seleziona figli ([<selectors>]) o discendenti (..[<selectors>]) di un valore di input.
Selector (selettore): Un singolo elemento all'interno di un segmento che prende il valore di input e produce una nodelist costituita da nodi figli del valore di input.
Singular Query (interrogazione singolare): Un'espressione JSONPath costruita da segmenti che sono stati sintatticamente ristretti in un certo modo (Sezione 2.3.5.1) in modo che, indipendentemente dal valore di input, l'espressione produca una nodelist contenente al massimo un nodo. Nota: le espressioni JSONPath che producono sempre una nodelist singolare ma non sono conformi alla sintassi nella Sezione 2.3.5.1 non sono singular queries.
1.1.1. JSON Values as Trees of Nodes (Valori JSON come alberi di nodi)
Questo documento modella l'argomento dell'interrogazione come un albero di valori JSON, ciascuno con il proprio nodo. Un nodo è il nodo radice o uno dei suoi discendenti.
Questo documento modella il risultato dell'applicazione di un'interrogazione all'argomento dell'interrogazione come una nodelist (una lista di nodi).
I nodi sono le parti selezionabili dell'argomento dell'interrogazione. Le sole parti di un oggetto che possono essere selezionate da un'interrogazione sono i valori di membro. I nomi dei membri e i membri (coppie nome/valore) non possono essere selezionati. Pertanto, i valori di membro hanno nodi, ma i membri e i nomi dei membri no. Analogamente, i valori di membro sono figli di un oggetto, ma i membri e i nomi dei membri no.
1.2. History (Storia)
Questo documento si basa sulla popolare proposta JSONPath di Stefan Gössner (datata 2007-02-21) [JSONPath-orig], si fonda sull'esperienza della diffusione capillare delle sue implementazioni e fornisce una specifica normativa per essa.
L'Appendice B descrive come JSONPath sia stato ispirato da XPath [XPath] per XML.
JSONPath era inteso come compagno leggero alle implementazioni JSON in linguaggi di programmazione come PHP e JavaScript, quindi invece di definire il proprio linguaggio di espressioni, come fece XPath, JSONPath delegava parti di un'interrogazione al runtime sottostante, ad esempio alla funzione eval() di JavaScript. Man mano che JSONPath fu implementato in più ambienti, le espressioni JSONPath divennero meno portabili. Ad esempio, l'elaborazione delle espressioni regolari era spesso delegata a un motore di espressioni regolari conveniente.
Questo documento mira a rimuovere tali dipendenze specifiche dell'implementazione e a servire come specifica JSONPath comune utilizzabile tra linguaggi di programmazione e ambienti. Ciò significa che la compatibilità all'indietro non è sempre raggiunta; un principio di progettazione di questo documento è aderire a un "consensus" tra implementazioni anche se grezzo, purché ciò non metta a rischio l'obiettivo di ottenere un linguaggio di interrogazione JSON stabile e utilizzabile.
Il termine JSONPath fu scelto per l'ispirazione a XPath e anche perché l'esito di un'interrogazione consiste in paths (percorsi) che identificano nodi nell'argomento dell'interrogazione JSON.
1.3. JSON Values (Valori JSON)
Il valore JSON a cui viene applicata un'interrogazione JSONPath è, per definizione, un valore JSON valido. Un valore JSON è spesso costruito analizzando un testo JSON.
L'analisi di un testo JSON in un valore JSON e ciò che accade se un testo JSON non rappresenta JSON valido non sono definiti da questo documento. Le Sezioni 4 e 8 di [RFC8259] identificano situazioni specifiche che possono essere conformi alla grammatica per i testi JSON ma non sono usi interoperabili di JSON, poiché possono causare comportamento imprevedibile. Questo documento non tenta di definire comportamento prevedibile per le interrogazioni JSONPath in queste situazioni.
In particolare, le sottosezioni "Semantics" delle Sezioni 2.3.1, 2.3.2, 2.3.5 e 2.5.2 descrivono comportamento che diventa imprevedibile quando il valore JSON per uno degli oggetti in esame è stato costruito da testo JSON che presenta più membri per un singolo oggetto che condividono lo stesso nome di membro ("duplicate names", nomi duplicati; vedere Sezione 4 di [RFC8259]). Inoltre, quando si seleziona un figlio per nome (Sezione 2.3.1) e si confrontano stringhe (Sezione 2.3.5.2.2), si assume che tali stringhe siano sequenze di valori scalari Unicode; il comportamento diventa imprevedibile se non lo sono (Sezione 8.2 di [RFC8259]).
1.4. Overview of JSONPath Expressions (Panoramica delle espressioni JSONPath)
Un'espressione JSONPath è applicata a un valore JSON, noto come argomento dell'interrogazione. L'output è una nodelist.
Un'espressione JSONPath consiste in un identificatore seguito da una serie di zero o più segmenti, ciascuno dei quali contiene uno o più selettori.
1.4.1. Identifiers (Identificatori)
L'identificatore del nodo radice $ si riferisce al nodo radice dell'argomento dell'interrogazione, vale a dire all'argomento nel suo insieme.
L'identificatore del nodo corrente @ si riferisce al nodo corrente nel contesto della valutazione di un'espressione di filtro (Sezione 2.3.5).
1.4.2. Segments (Segmenti)
I segmenti selezionano figli ([<selectors>]) o discendenti (..[<selectors>]) di un valore di input.
I segmenti possono usare la bracket notation (notazione con parentesi quadre), ad esempio:
$['store']['book'][0]['title']
o la più compatta dot notation (notazione a punto), ad esempio:
$.store.book[0].title
La notazione con parentesi quadre contiene uno o più selettori (separati da virgola) di qualsiasi tipo. I selettori sono dettagliati nella sezione successiva.
Un'espressione JSONPath può usare una combinazione di notazioni con parentesi quadre e a punto.
Questo documento tratta la notazione con parentesi quadre come canonica e definisce la notazione a punto abbreviata in termini di notazione con parentesi quadre. Esempi e descrizioni usano la forma abbreviata ove conveniente.
1.4.3. Selectors (Selettori)
Un name selector (selettore per nome), ad esempio 'name', seleziona un figlio denominato di un oggetto.
Un index selector (selettore per indice), ad esempio 3, seleziona un figlio indicizzato di un array.
Nell'espressione [], un wildcard * (Sezione 2.3.2) seleziona tutti i figli di un nodo, e nell'espressione ..[] seleziona tutti i discendenti di un nodo.
Un array slice (fetta di array) start:end:step (Sezione 2.3.4) seleziona una serie di elementi da un array, fornendo una posizione iniziale, una posizione finale e un valore di step opzionale che sposta la posizione dall'inizio alla fine.
Un'espressione di filtro ?<logical-expr> seleziona determinati figli di un oggetto o array, come in:
$.store.book[[email protected] < 10].title
1.4.4. Summary (Riepilogo)
La Tabella 1 fornisce una breve panoramica della sintassi JSONPath.
| Elemento sintattico | Descrizione |
|---|---|
| $ | identificatore del nodo radice (Sezione 2.2) |
| @ | identificatore del nodo corrente (Sezione 2.3.5) |
| (valido solo all'interno dei selettori di filtro) | |
[<selectors>] | child segment (Sezione 2.5.1): seleziona |
| zero o più figli di un nodo | |
| .name | abbreviazione per ['name'] |
| .* | abbreviazione per [*] |
..[<selectors>] | descendant segment (Sezione 2.5.2): |
| seleziona zero o più discendenti di un nodo | |
| ..name | abbreviazione per ..['name'] |
| ..* | abbreviazione per ..[*] |
| 'name' | name selector (Sezione 2.3.1): seleziona un |
| figlio denominato di un oggetto | |
| * | wildcard selector (Sezione 2.3.2): seleziona |
| tutti i figli di un nodo | |
| 3 | index selector (Sezione 2.3.3): seleziona un |
| figlio indicizzato di un array (da 0) | |
| 0💯5 | array slice selector (Sezione 2.3.4): |
| start:end:step per array | |
?<logical-expr> | filter selector (Sezione 2.3.5): seleziona |
| figli particolari usando un'espressione | |
| logica | |
| length(@.foo) | function extension (Sezione 2.4): invoca |
| una funzione in un'espressione di filtro |
Tabella 1: Panoramica della sintassi JSONPath
1.5. JSONPath Examples (Esempi JSONPath)
Questa sezione è informativa. Fornisce esempi di espressioni JSONPath.
Gli esempi si basano sul semplice valore JSON mostrato nella Figura 1, che rappresenta una libreria (che ha anche una bicicletta).
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 399
}
}
}
Figura 1: Valore JSON di esempio
La Tabella 2 mostra alcune interrogazioni JSONPath che potrebbero essere applicate a questo esempio e i loro risultati attesi.
| JSONPath | Risultato atteso |
|---|---|
| $.store.book[*].author | gli autori di tutti i libri nel negozio |
| $..author | tutti gli autori |
| $.store.* | tutto ciò che è nel negozio, vale a dire |
| alcuni libri e una bicicletta rossa | |
| $.store..price | i prezzi di tutto ciò che è nel negozio |
| $..book[2] | il terzo libro |
| $..book[2].author | l'autore del terzo libro |
| $..book[2].publisher | risultato vuoto: il terzo libro non ha |
| un membro "publisher" | |
| $..book[-1] | l'ultimo libro in ordine |
| $..book[0,1] | i primi due libri |
| $..book[:2] | |
| $..book[[email protected]] | tutti i libri con un numero ISBN |
| $..book[[email protected]<10] | tutti i libri più economici di 10 |
| $..* | tutti i valori di membro e gli elementi |
| di array contenuti nel valore di input |
Tabella 2: Esempi di espressioni JSONPath e risultati attesi quando applicati al valore JSON di esempio