Guida alle Query JSONPath: Estrarre Dati Come un Professionista
JSONPath è un linguaggio di query per JSON, simile a come XPath funziona per XML. Quando hai a che fare con risposte API complesse e profondamente annidate, JSONPath ti permette di estrarre esattamente i dati di cui hai bisogno senza scrivere cicli e condizionali. Questa guida copre la sintassi, gli operatori e i pattern reali di cui hai bisogno.
Perché JSONPath?
Considera una tipica risposta API con dati annidati:
{
"store": {
"books": [
{ "title": "Clean Code", "author": "Robert Martin", "price": 32.99, "tags": ["programming", "best-practices"] },
{ "title": "Design Patterns", "author": "Gang of Four", "price": 44.99, "tags": ["programming", "architecture"] },
{ "title": "The Pragmatic Programmer", "author": "Hunt & Thomas", "price": 39.99, "tags": ["programming", "career"] }
],
"music": [
{ "title": "Kind of Blue", "artist": "Miles Davis", "price": 12.99 }
]
}
}
Per ottenere tutti i titoli dei libri, potresti scrivere un ciclo — oppure usare JSONPath: $.store.books[*].title
Sintassi di Base
| Espressione | Descrizione |
|---|---|
$ | Oggetto radice |
. | Operatore figlio |
.. | Discesa ricorsiva (cerca a tutti i livelli) |
[*] | Wildcard (tutti gli elementi) |
[n] | Indice array (base 0) |
[n,m] | Indici multipli |
[start:end:step] | Slice di array |
[?()] | Espressione filtro |
@ | Elemento corrente (nei filtri) |
Notazione a Punti vs Notazione a Parentesi
Entrambe le notazioni accedono alle proprietà, ma la notazione a parentesi è necessaria per i caratteri speciali:
# Notazione a punti
$.store.books[0].title
# Notazione a parentesi (equivalente)
$['store']['books'][0]['title']
# Necessaria per chiavi con caratteri speciali
$['store']['price-range']
Operazioni sugli Array
Indicizzazione
$.store.books[0] # Primo libro
$.store.books[-1] # Ultimo libro
$.store.books[0,2] # Primo e terzo libro
Slicing
$.store.books[0:2] # Primi due libri (indice 0 e 1)
$.store.books[1:] # Tutti i libri tranne il primo
$.store.books[:2] # Primi due libri
$.store.books[::2] # Un libro ogni due
Wildcards
$.store.books[*].title # Tutti i titoli dei libri
$.store.* # Tutte le collezioni dello store (books, music)
$..title # Tutti i titoli a qualsiasi profondità
$..price # Tutti i prezzi a qualsiasi profondità
L'operatore di discesa ricorsiva (..) è particolarmente potente per estrarre valori indipendentemente dalla loro posizione nella gerarchia.
Espressioni Filtro
I filtri selezionano elementi in base a condizioni:
# Libri con prezzo inferiore a $40
$.store.books[?(@.price < 40)]
# Libri di un autore specifico
$.store.books[?(@.author == 'Robert Martin')]
# Libri con più di 2 tag
$.store.books[?(@.tags.length > 2)]
# Libri che hanno una proprietà 'price'
$.store.books[?(@.price)]
Combinare i Filtri
# Libri sotto $40 con tag programming
$.store.books[?(@.price < 40 && @.tags[0] == 'programming')]
Esempi Reali
Estrazione da Risposte API
GitHub API — ottenere tutti i nomi dei repository:
$[*].name
Weather API — ottenere la temperatura di oggi:
$.daily[0].temp.day
E-commerce API — ottenere tutte le immagini dei prodotti:
$.products[*].images[0].url
Estrazione di Configurazione
Docker Compose — ottenere tutti i nomi dei servizi:
$.services.*~
Package.json — ottenere tutti i nomi delle dipendenze:
$.dependencies.*~
JSONPath vs jq
JSONPath e jq sono entrambi strumenti di query JSON, ma servono contesti diversi:
| Funzionalità | JSONPath | jq |
|---|---|---|
| Ambiente | Librerie, API | Riga di comando |
| Sintassi | Ispirata a XPath | Funzionale personalizzata |
| Trasformazione | Solo query | Query + trasformazione |
| Standard | RFC 9535 | Standard de facto |
Per l'elaborazione JSON da riga di comando, jq è più potente. Per incorporare query nelle applicazioni o utilizzarle in strumenti web, JSONPath è più ampiamente supportato.
Prova le espressioni JSONPath in modo interattivo con il nostro JSON Path Explorer. Incolla il tuo JSON, scrivi una query e vedi i risultati istantaneamente.
Esempi di Implementazione
JavaScript (jsonpath-plus)
const { JSONPath } = require('jsonpath-plus');
const result = JSONPath({
path: '$.store.books[?(@.price < 40)].title',
json: data
});
// ["Clean Code", "The Pragmatic Programmer"]
Python (jsonpath-ng)
from jsonpath_ng import parse
expr = parse('$.store.books[*].title')
titles = [match.value for match in expr.find(data)]
RFC 9535: Lo Standard JSONPath
A febbraio 2024, JSONPath è stato ufficialmente standardizzato come RFC 9535. Questo risolve le inconsistenze storiche tra le implementazioni. Comportamenti chiave standardizzati:
- Gli indici degli array partono da 0
- Le espressioni filtro usano
@per l'elemento corrente - Il confronto tra stringhe è case-sensitive
- Il risultato è sempre un array di valori corrispondenti
Se stai scegliendo una libreria JSONPath, preferisci una che supporti RFC 9535 per un comportamento coerente.
FAQ
Qual è la differenza tra JSONPath e JSON Pointer?
JSONPath è un linguaggio di query che può trovare più valori usando wildcards e filtri. JSON Pointer (RFC 6901) è una sintassi di percorso semplice che indirizza esattamente un valore: /store/books/0/title. Usa JSONPath quando hai bisogno di cercare o filtrare; usa JSON Pointer quando conosci il percorso esatto.
JSONPath può modificare i dati JSON?
Il JSONPath standard è di sola lettura — estrae ma non modifica i dati. Alcune librerie estendono JSONPath con operazioni di set/delete, ma queste non sono standard. Per le trasformazioni, considera jq (riga di comando) o scrivi codice applicativo. Per visualizzare ed esplorare la struttura JSON, il nostro JSON Formatter ti aiuta a capire i dati prima di scrivere le query.
Risorse Correlate
- JSON Path Explorer — Testa le espressioni JSONPath nel tuo browser
- Best Practice per la Formattazione JSON — Struttura il tuo JSON per query più semplici
- Guida alla Validazione JSON Schema — Valida la struttura che le tue query JSONPath si aspettano