Utilizzo delle funzioni JSON
FileMaker Pro offre diverse funzioni di testo che permettono all'app personalizzata di analizzare e modificare i dati JSON da altre funzioni FileMaker o da altre origini, come i servizi Web che trasferiscono i dati in formato JSON attraverso un'API REST.
Per ulteriori informazioni sul formato dati JSON, consultare il sito json.org.
Negli esempi riportati in questa sezione vengono utilizzati i dati JSON di una panetteria che mette a disposizione dei propri clienti l'elenco dei prodotti in formato JSON tramite un'API REST. Quanto riportato di seguito restituisce l'elenco delle specialità del giorno come dati JSON nella variabile $$JSON:
Imposta variabile [$url; "https://panificio.example.com/rest/api/prodotti"]
Inserisci da URL [Con finestra di dialogo: Disattivata ; Destinazione: $$JSON; $url; Verifica certificati SSL; Opzioni cURL: "--data elenco=specialità"]
Per i dati restituiti in $$JSON e utilizzati in questi esempi, vedere Dati JSON di esempio.
Formattazione dei dati JSON
I dati JSON non richiedono spazi o terminazioni di riga tra gli elementi. Tuttavia, per facilitare la lettura dei dati durante il debug dei problemi, utilizzare la funzione JSONFormatElements che aggiunge tabulazioni e terminazioni di riga, come mostrato in Dati JSON di esempio.
Analisi dei dati JSON
Utilizzare le seguenti funzioni JSON per analizzare i dati JSON, ovvero per ottenere chiavi, valori o interi oggetti o matrici JSON da elaborare:
-
JSONGetElement – Esegue una query sui dati JSON per un elemento (un oggetto, una matrice o un valore)
-
JSONListKeys – Elenca i nomi degli oggetti (chiavi) o gli indici di matrice nei dati JSON
-
JSONListValues – Elenca i valori nei dati JSON
Il primo parametro di queste funzioni, json
, specifica il campo Testo, la variabile o l'espressione di testo che contiene dati JSON validi su cui agire.
Il secondo parametro, chiaveOIndiceOPercorso
, specifica la parte dei dati JSON su cui agire:
-
chiave – il nome di una chiave in un oggetto JSON
-
indice – l'indice di un elemento in una matrice JSON (il primo elemento ha indice 0)
-
percorso – una stringa gerarchica di nomi di chiavi, indici di matrice o entrambi
Sono supportati i seguenti due tipi di sintassi per il parametro chiaveOIndiceOPercorso
: notazione con punti e notazione con parentesi.
Sintassi del parametro |
Significato |
|
Notazione con punti | Notazione con parentesi | |
---|---|---|
|
|
Il livello principale, se è il primo carattere (opzionale nella notazione con punti) |
|
|
Elementi all'indice n di una matrice al livello principale |
|
|
La chiave di un oggetto nome al livello principale |
|
|
Un oggetto nomeC, discendente di nomeB e nomeA |
|
|
Il primo elemento della matrice nell'oggetto nomeA, al terzo livello in una serie di matrici nidificate |
|
|
L'ultimo elemento di un array |
|
|
La posizione dopo l'ultimo elemento di un array. Utilizzare nella funzione JSONSetElement per aggiungere un elemento alla fine di un array. |
La differenza tra la notazione con punti e la notazione con parentesi consiste nel fatto che, invece di utilizzare punti (.
) per separare i nomi di chiavi, la notazione con parentesi racchiude i nomi tra virgolette singole ('
) e parentesi quadre ([]
). È possibile utilizzare qualsiasi tra le notazioni in chiaveOIndiceOPercorso
. Tuttavia, è necessario usare la notazione con parentesi se i nomi di chiavi comprendono punti, in modo che il parser JSON possa identificare correttamente il nome di chiave completo. Ad esempio, se una chiave al livello principale dell'oggetto JSON è "layout.response"
, allora chiaveOIndiceOPercorso
sarà "['layout.response']"
.
Il seguente script di esempio crea un record per ogni prodotto in una matrice JSON. Supponendo che i Dati JSON di esempio siano memorizzati nella variabile $$JSON, lo script utilizza JSONListValues per ottenere i contenuti della matrice prodotto come elenco di valori e utilizza ConteggioValore per determinare il numero dei prodotti dell'elenco. Creando ogni volta un record per un prodotto attraverso il ciclo, lo script utilizza RicavaValore per ottenere l'oggetto JSON per un prodotto dell'elenco e imposta i campi sui valori ottenuti utilizzando JSONGetElement. Poiché le funzioni JSON analizzano l'intero oggetto JSON che è stato loro passato, può essere più efficiente utilizzare le funzioni JSON su oggetti JSON più piccoli all'interno di un ciclo che viene ripetuto più volte.
Imposta variabile [$ElencoProdotti; Valore: JSONListValues ( $$JSON ; "panificio.prodotto" )]
Imposta variabile [$ConteggioProdotti; Valore: ConteggioValore ( $ElencoProdotti )]
Imposta variabile [$i; Valore: 1]
If [$ConteggioProdotti > 0]
Loop [Scarica: Sempre]
Nuovo record/richiesta
Imposta variabile [$Prodotto; Valore: RicavaValore ( $ElencoProdotti ; $i )]
Imposta campo [Prodotti::ID; JSONGetElement ( $Prodotto ; "id" )]
Imposta campo [Prodotti::Prezzo; JSONGetElement ( $Prodotto ; "prezzo" )]
Imposta campo [Prodotti::Magazzino; JSONGetElement ( $Prodotto ; "magazzino" )]
Salva record/richieste [Con finestra di dialogo: Disattivata]
Imposta variabile [$i; Valore: $i +1]
Exit Loop If [$i > $ConteggioProdotti]
End Loop
End If
Modifica e aggiunta di elementi dati JSON
Per modificare valori e aggiungere elementi nei dati JSON, utilizzare la funzione JSONSetElement. I parametri json
e chiaveOIndiceOPercorso
in questa funzione agiscono come descritto in Analisi dei dati JSON. Se chiaveOIndiceOPercorso
specifica un elemento esistente, il valore di questo elemento viene modificato; se l'elemento non esiste, ne viene aggiunto uno nuovo.
JSONSetElement imposta l'elemento specificato sul parametro valore
. È possibile specificare qualsiasi valore JSON valido, da una stringa o un numero semplici a un oggetto o una matrice complessi.
Il parametro tipo
specifica il tipo di dati in valore
in modo che il parser JSON segua regole rigide nella gestione di ciascun tipo di dati. Per i tipi di dati supportati, vedere la funzione JSONSetElement. Per inserire i dati in json
, già formattato come elemento JSON valido, impostare tipo
su JSONRaw
.
L'esempio di seguito aggiunge le coppie chiave-valore per un nuovo prodotto a un oggetto JSON vuoto. Quindi il nuovo oggetto viene aggiunto alla fine della matrice prodotto nella variabile $$JSON (vedere Dati JSON di esempio).
Imposta variabile [$NuovoProdotto; Valore:
JSONSetElement ( "{}" ;
["id" ; "FB4" ; JSONString ] ;
["nome"; "Torta alla vaniglia"; JSONString] ;
["prezzo"; 17.5; JSONNumber] ;
["magazzino"; 12; JSONNumber] ;
["categoria"; "Torte"; JSONString] ;
["specialità"; true; JSONBoolean]
) ]
Imposta variabile [$IndiceSucc; Valore:
ConteggioValore (
JSONListKeys ( $$JSON ; "panificio.prodotto" )
) ]
Imposta variabile [$$JSON; Valore:
JSONSetElement (
$$JSON ; "panificio.prodotto[" & $IndiceSucc & "]" ; $NuovoProdotto ;
JSONObject
) ]
Un'altra funzione JSON che crea un elemento JSON è la funzione JSONMakeArray. Converte un elenco di valori in un array JSON. Per accettare dati formattati in modi diversi, questa funzione consente di specificare il carattere che separa ciascun valore e il tipo di dati JSON da utilizzare.
Eliminazione di elementi dati JSON
Per eliminare un elemento, utilizzare la funzione JSONDeleteElement. I parametri json
e chiaveOIndiceOPercorso
in questa funzione agiscono come descritto in Analisi dei dati JSON. Il parametro chiaveOIndiceOPercorso
deve specificare un elemento esistente in json
.
L'esempio di seguito elimina l'elemento nella matrice prodotto la cui chiave "id" ha il valore "FB3" nella variabile $$JSON (vedere Dati JSON di esempio).
Imposta variabile [$ConteggioProdotti; Valore:
ConteggioValore (
JSONListKeys ( $$JSON ; "panificio.prodotto" )
) ]
Imposta variabile [$i; Valore: 0]
If [$ConteggioProdotti > 0]
Loop [Scarica: Sempre]
Imposta variabile [$ID; Valore:
JSONGetElement ( $$JSON ; "panificio.prodotto[" & $i & "]id" )]
If [ $ID = "FB3" ]
Imposta variabile [$$JSON; Valore:
JSONDeleteElement ( $$JSON ; "panificio.prodotto[" & $i & "]" )]
Esci dallo script [Risultato testo: 0]
End If
Imposta variabile [$i; Valore: $i +1]
Exit Loop If [$i ≥ $ConteggioProdotti]
End Loop
End If
Ottimizzazione delle prestazioni JSON
Ogni volta che una funzione JSON analizza un input di testo, il parser JSON ne crea una rappresentazione binaria (non di testo) per rendere più veloce la successiva elaborazione del JSON. Esistono un meccanismo automatico per analizzare e memorizzare il JSON nella cache e uno esplicito: la funzione JSONParse.
Sfruttare la memorizzazione automatica di JSON nella cache
L'analisi richiede tempo, quindi le funzioni JSON salvano in memoria la rappresentazione binaria dell'ultimo JSON analizzato. Questo riduce la necessità di analizzare di nuovo lo stesso JSON in un secondo momento. Viene mantenuta una sola cache automatica. Quando viene analizzato un valore JSON diverso, il valore JSON precedentemente memorizzato nella cache viene eliminato. Il JSON analizzato esiste solo nella memoria: nelle variabili, nei parametri di script e nei calcoli. Quando viene utilizzato per impostare il valore di un campo, viene memorizzato nel campo come testo.
Questo esempio illustra, per numero di riga, quando il testo JSON inizialmente memorizzato in $JSON1 e $JSON2 viene analizzato e quando no.
Imposta variabile [ $id ; JSONGetElement ( $JSON1 ; "id" ) ]
Imposta variabile [ $nome ; JSONGetElement ( $JSON1 ; "nome" ) ]
Imposta variabile [ $prezzo ; JSONGetElement ( $JSON2 ; "prezzo" ) ]
Imposta variabile [ $categoria ; JSONGetElement ( $JSON1 ; "categoria" ) ]
-
$JSON1 viene analizzato e la rappresentazione binaria viene salvata nella cache.
-
$JSON1 non deve essere di nuovo analizzato.
-
$JSON2 viene analizzato e memorizzato nella cache, sostituendo il valore precedentemente memorizzato nella cache.
-
$JSON1 viene analizzato di nuovo perché non era più memorizzato nella cache.
Quindi, per sfruttare la memorizzazione automatica nella cache, l'ideale è lavorare con un valore JSON alla volta (nell'esempio di cui sopra scambiare le righe 3 e 4 per evitare di analizzare nuovamente $JSON1).
Utilizzo di JSONParse
Per analizzare e memorizzare esplicitamente la rappresentazione binaria di un valore JSON in una variabile nonché nella cache automatica, utilizzare la funzione JSONParse. Il parametro json
della funzione è qualsiasi espressione di testo che valuta i dati JSON, sia che si tratti di testo formattato come JSON in un campo o in una stringa, o di JSON già analizzato in una variabile.
Il seguente esempio analizza il testo JSON:
Imposta variabile [ $JSON1 ; "{ \"prodotto\": {\"id\": \"FB1\"} }" ]
Imposta variabile [ $JSON1 ; JSONParse ( $JSON1 ) ]
-
$JSON1 è solo la rappresentazione del testo che si presenta così:
{ "prodotto": {"id": "FB1"} }
-
Dopo aver usato JSONParse:
-
La cache automatica contiene la rappresentazione binaria.
-
La variabile $JSON1 contiene sia il testo che le rappresentazioni binarie.
-
Se JSONParse non viene utilizzato, quindi in questo esempio:
Imposta variabile [ $JSON1 ; "{ \"prodotto\": {\"id\": \"FB1\"} }" ]
Imposta variabile [ $JSON2 ; JSONGetElement ( $JSON1 ; "prodotto") ]
-
$JSON1 è solo la rappresentazione di testo, come prima.
-
Dopo aver usato JSONGetElement:
-
La cache automatica contiene la rappresentazione binaria.
-
$JSON2 contiene la rappresentazione binaria di
{"id": "FB1"}
. -
$JSON1 è ancora solo la rappresentazione del testo. Il testo è stato analizzato, ma la rappresentazione binaria è solo nella cache automatica.
-
Confrontare questa situazione con ciò che accade quando si aggiunge JSONParse:
Imposta variabile [ $JSON1 ; "{ \"prodotto\": {\"id\": \"FB1\"} }" ]
Imposta variabile [ $JSON1 ; JSONParse ( $JSON1 ) ]
Imposta variabile [ $JSON2 ; JSONGetElement ( $JSON1 ; "prodotto") ]
-
$JSON1 è solo la rappresentazione del testo, come prima.
-
Dopo aver usato JSONParse:
-
La cache automatica contiene la rappresentazione binaria.
-
$JSON1 contiene sia il testo che le rappresentazioni binarie.
-
-
Dopo aver usato JSONGetElement:
-
$JSON2 contiene la rappresentazione binaria di
{"id": "FB1"}
.La rappresentazione del testo non è memorizzata in $JSON2 a questo punto, ma viene generata in seguito solo se necessario.
-
Si noti che JSONGetElement non necessitava di analizzare $JSON1 nella riga 3, perché poteva utilizzare la rappresentazione binaria memorizzata nella cache con $JSON1 nella riga 2.
Così come l'analisi del testo per ottenere una rappresentazione binaria richiede tempo, anche la conversione di JSON binario in testo ne richiede. Per questo, il risultato di funzioni JSON come JSONGetElement e JSONSetElement è solo la rappresentazione binaria. La rappresentazione di testo viene creata solo quando necessario, ad esempio quando si memorizza una variabile (come $JSON2) in un campo o si visualizza una variabile nel Visualizzatore dati.
È possibile usare la funzione complementare JSONParsedState per scoprire se un dato valore JSON ha analizzato il JSON memorizzato con esso, se il JSON è valido e qual è il tipo di JSON.
Migliori metodologie operative
Quando si elaborano ripetutamente strutture JSON di grandi dimensioni (soprattutto nei loop) o si lavora con più elementi nei dati JSON, l'ordine delle operazioni può fare una grande differenza in termini di prestazioni.
Per sfruttare la memorizzazione automatica nella cache di JSON, è meglio non alternare le seguenti operazioni: caricare i dati JSON da un campo su cui lavorare, passare a un campo diverso su cui lavorare, quindi tornare al primo campo. Ogni volta che una funzione JSON elabora del testo JSON diverso, il JSON precedentemente memorizzato nella cache viene eliminato, cosicché il testo deve essere nuovamente analizzato. Ad esempio, questo rallenta al massimo le prestazioni:
# Esempio - Non efficiente
Imposta variabile [ $nomel ; Valore: JSONGetElement ( Tabella::JSON1 ; "nome" ) ]
Imposta variabile [ $nome2 ; Valore: JSONGetElement ( Tabella::JSON2 ; "nome" ) ]
Imposta variabile [ $id1 ; Valore: JSONGetElement ( Tabella::JSON1 ; "id" ) ]
Imposta variabile [ $id2 ; Valore: JSONGetElement ( Tabella::JSON2 ; "id" ) ]
Semplicemente riordinando le istruzioni in modo da fare tutto il lavoro sugli stessi dati JSON prima di lavorare su dati JSON diversi, la cache automatica funziona in modo favorevole per l'utente, evitando di analizzare due volte i dati dello stesso campo.
# Esempio - Meglio
Imposta variabile [ $nomel ; Valore: JSONGetElement ( Tabella::JSON1 ; "nome" ) ]
Imposta variabile [ $id1 ; Valore: JSONGetElement ( Tabella::JSON1 ; "id" ) ]
Imposta variabile [ $nome2 ; Valore: JSONGetElement ( Tabella::JSON2 ; "nome" ) ]
Imposta variabile [ $id2 ; Valore: JSONGetElement ( Tabella::JSON2 ; "id" ) ]
Il metodo migliore e più flessibile è utilizzare la funzione JSONParse per ottenere il testo JSON da ogni origine, analizzarlo e memorizzarlo in una variabile. In questo modo viene analizzato solo una volta. Quindi non importa in quale ordine si eseguono le ulteriori operazioni (come ottenere o impostare elementi) poiché quelle funzioni JSON possono utilizzare le variabili, che contengono le rappresentazioni binarie già analizzate.
# Esempio - Ottimale
Imposta variabile [ $JSON1 ; Valore: JSONParse ( Tabella::JSON1 ) ]
Imposta variabile [ $JSON2 ; Valore: JSONParse ( Tabella::JSON2 ) ]
Imposta variabile [ $nomel ; Valore: JSONGetElement ( $JSON1 ; "nome" ) ]
Imposta variabile [ $nome2 ; Valore: JSONGetElement ( $JSON2 ; "nome" ) ]
Imposta variabile [ $id1 ; Valore: JSONGetElement ( $JSON1 ; "id" ) ]
Imposta variabile [ $id2 ; Valore: JSONGetElement ( $JSON2 ; "id" ) ]
Gestione degli errori nei dati JSON
Se si verifica un errore durante l'analisi del parametro json
, le funzioni JSON restituiscono "?" seguito da un messaggio di errore del parser JSON.
Ad esempio, se in Dati JSON di esempio manca ":" dopo la chiave "panificio", questo calcolo
JSONGetElement ( $$JSON ; "panificio.prodotto[0]id" )
restituisce questo messaggio di errore:
? * Line 3, Column 2
Missing ':' after object member name
* Line 13, Column 5
Extra non-whitespace after JSON value.
Per determinare se i dati JSON sono validi prima di utilizzarli, utilizzare la funzione JSONFormatElements e controllare se il primo carattere è "?". Ad esempio:
Imposta variabile [$risultato; Valore: JSONFormatElements ( $$JSON )]
If [Sinistra ( $risultato ; 1 ) = "?" ]
# $$JSON contiene dati JSON non validi.
End If
In alternativa, per determinare la validità dei dati JSON e il tipo di JSON specifico prima di usarli, utilizzare la funzione funzione JSONGetElementType. Ad esempio, per verificare se $$JSON è un oggetto JSON valido:
Imposta variabile [$risultato; Valore: JSONGetElementType( $$JSON, "" ) ]
If [ $result ≠ JSONObject ]
# $$JSON contiene dati JSON non validi.
End If
Un altro strumento per rilevare gli errori è la funzione JSONParsedState. Può indicare se i dati JSON sono stati analizzati e sono validi e, in caso affermativo, di che tipo di dati JSON si tratta.
Imposta variabile [ $risultato ; Valore: JSONParse ( $$JSON ) ]
Imposta variabile [ $StatoAnalisi ; Valore: JSONParsedState ( $risultato ) ]
If [ $StatoAnalisi < 0 ]
# $$JSON è stato analizzato ma contiene dati JSON non validi.
Else If [ $StatoAnalisi = 0 ]
# $$JSON non è stato analizzato.
Else If [ $StatoAnalisi > 0 ]
# $$JSON è stato analizzato ed è valido. $StatoAnalisi indica il tipo di JSON. Imposta variabile [ $tipo ; Valore:
Casi (
$StatoAnalisi = JSONString ; "Il tipo JSON è JSONString" ;
$StatoAnalisi = JSONNumber ; "Il tipo JSON è JSONNumber" ;
$StatoAnalisi = JSONObject ; "Il tipo JSON è JSONObject" ;
$StatoAnalisi = JSONArray ; "Il tipo JSON è JSONArray" ;
$StatoAnalisi = JSONBoolean ; "Il tipo JSON è JSONBoolean" ;
$StatoAnalisi = JSONNull ; "Il tipo JSON è JSONNull"
)
]
Mostra finestra personalizz. [ $tipo ]
End If
Dati JSON di esempio
I dati JSON di esempio di seguito contengono un oggetto "panificio" che ha una matrice di tre oggetti "prodotto", ognuno con diverse coppie chiave-valore.
{
"panificio" :
{
"prodotto" :
[
{
"id" : "FB1",
"nome" : "Donuts",
"prezzo": 1.99,
"magazzino" : 43,
"categoria" : "Pani",
"specialità" : true
},
{
"id" : "FB2",
"prezzo": 22.5,
"nome" : "Torta al cioccolato",
"magazzino" : 23,
"categoria" : "Torte",
"specialità" : true
},
{
"id" : "FB3",
"prezzo": 3.95,
"nome" : "Baguette",
"magazzino" : 34,
"categoria" : "Pani",
"specialità" : true
}
]
}
}
Note
-
Il parser JSON conserva l'ordine degli elementi in una matrice, ma non l'ordine degli elementi in un oggetto. Pertanto, le funzioni JSON possono restituire elementi in un oggetto in un ordine diverso da quello specificato.
-
Nei dati JSON, i valori numerici decimali devono utilizzare un punto "." come separatore decimale indipendentemente dal separatore specificato dalle formattazioni di sistema del computer in uso o dalle formattazioni utilizzate al momento della creazione del file FileMaker Pro.