Werken met de JSON-functies
FileMaker Pro heeft verschillende tekstfuncties waarmee uw app op maat JSON-gegevens uit andere bronnen kan parseren en wijzigen, zoals webservices die gegevens in JSON-structuur via een REST API overbrengen.
Raadpleeg json.org voor meer informatie over de JSON-gegevensstructuur.
De voorbeelden in dit onderwerp maken gebruik van JSON-gegevens van een bakkerij die de productlijst beschikbaar stelt voor klanten in JSON-formaat via een REST-API. Het volgende geeft als resultaat de lijst met speciale gebakjes als JSON-gegevens in de $$JSON-variabele:
Variabele instellen [ $url ; "https://bakkerij.voorbeeld.com/rest/api/producten" ]
Invoegen vanuit URL [ Met dialoogvenster: Uit; Doel: $$JSON ; $url ; SSL-certificaten verifiëren ; cURL-opties: "--data list=specials" ]
Zie Voorbeeld van JSON-gegevens voor de gegevens die in $$JSON worden geretourneerd en in deze voorbeelden worden gebruikt.
JSON-gegevens opmaken
JSON-gegevens vereisen geen spaties of regeleinden tussen elementen. Om de gegevens toch beter te kunnen lezen wanneer u problemen oplost, gebruikt u de JSONFormatElements functie die tabs en regeleinden toevoegt, zoals u in Voorbeeld van JSON-gegevens kunt zien.
JSON-gegevens parseren
Gebruik de volgende JSON-functies om JSON-gegevens te parseren. Hieronder verstaan we het ophalen van sleutels, waarden of complete JSON-objecten of arrays die u verder kunt verwerken:
-
JSONGetElement – Vraagt JSON-gegevens op voor een element (een object, array of waarde)
-
JSONListKeys – Geeft een lijst met de objectnamen (sleutels) of array-indexen in JSON-gegevens
-
JSONListValues – Geeft een lijst met de waarden in JSON-gegevens
De eerste parameter van deze functies, json
, geeft het tekstveld, de variabele of de tekstuitdrukking op die geldige JSON-gegevens bevat die kunnen worden bewerkt.
De tweede parameter, SleutelOfIndexOfPad
, geeft het deel van de JSON-gegevens op die moeten worden bewerkt:
-
sleutel – de naam van een sleutel in een JSON-object
-
index – de index van een element in een JSON-array (het eerste element heeft de index 0)
-
pad – een hiërarchische reeks sleutelnamen, array-indexen of beide
De volgende twee syntaxistypen voor de parameter SleutelOfIndexOfPad
worden ondersteund: notatie met punten en notatie met punthaken.
Syntaxis voor parameter |
Betekent |
|
Notatie met punten | Notatie met punthaken | |
---|---|---|
|
|
Het hoofdniveau, als het het eerste teken is (optioneel in notatie met punten) |
|
|
Elementen bij index n van een array op het hoofdniveau |
|
|
De sleutel van een object met de naam naam op het hoofdniveau |
|
|
Een object met de naam naamC dat een onderliggend element van naamB en naamA is |
|
|
Het eerste element van de array in het object naamA, dat zich op het derde niveau in een reeks geneste arrays bevindt |
|
|
Het laatste element van een array |
|
|
De positie na het laatste element van een array. Gebruik in de JSONSetElement functie om een element toe te voegen aan het einde van een array. |
Het verschil tussen de notatie met punten en die met punthaken is dat, in plaats dat er punten (.
) worden gebruikt om sleutelnamen te scheiden, de sleutelnamen door enkele aanhalingstekens ('
) en punthaken ([]
) worden omsloten. Beide notaties kunnen in SleutelOfIndexOfPad
worden gebruikt. U moet echter de notatie met punthaken gebruiken als de sleutelnamen punten bevatten, zodat de JSON-parser de hele sleutelnaam op de juiste wijze kan herkennen. Als bijvoorbeeld een sleutel op het hoofdniveau van een JSON-object "layout.response"
is, dan wordt SleutelOfIndexOfPad
"['layout.response']".
Met het volgende voorbeeldscript wordt een record voor elk product in een JSON-array gemaakt. Aangenomen dat de Voorbeeld van JSON-gegevens worden opgeslagen in de variabele $$JSON, maakt het script gebruik van JSONListValues om de inhoud van de productarray op te halen als een lijst met waarden en wordt ValueCount gebruikt om het aantal producten in de lijst te bepalen. Telkens wanneer de lus wordt doorlopen wordt een record voor een product gemaakt en wordt gebruikgemaakt van GetValue om het JSON-object voor een product uit de lijst te halen en worden de velden ingesteld op de waarden die met behulp van JSONGetElement zijn verkregen. Omdat de JSON-functies het hele JSON-object parseren dat aan de functies wordt doorgegeven, kan het efficiënter zijn de JSON-functies te gebruiken voor kleinere JSON-objecten in een lus die vaak wordt herhaald.
Variabele instellen [ $ProductList ; Waarde: JSONListValues ($$JSON ; "bakkerij.product") ]
Variabele instellen [ $ProductTelling ; Waarde: ValueCount ( $ProductList ) ]
Variabele instellen [ $i; Waarde: 1 ]
If [ $ProductTelling > 0 ]
Loop [ Wissen: Altijd ]
Nieuwe record/nieuw verzoek
Variabele instellen [ $Product ; Waarde: GetValue ( $ProductList ; $i ) ]
Veld instellen [ Producten::ID ; JSONGetElement ( $Product ; "id" ) ]
Veld instellen [ Producten::Prijs ; JSONGetElement ( $Product ; "prijs" ) ]
Veld instellen [ Producten::Voorraad ; JSONGetElement ( $Product ; "voorraad" ) ]
Records/verzoeken vastleggen [ Met dialoogvenster: Uit ]
Veld instellen [ $i ; Waarde: $i + 1 ]
Exit Loop If [ $i > $ProductTelling ]
End Loop
End If
JSON-gegevenselementen wijzigen en toevoegen
Gebruik de JSONSetElement functie om in JSON-gegevens waarden te wijzigen en elementen toe te voegen. De parameters json
en SleutelOfIndexOfPad
werken in deze functie zoals beschreven in JSON-gegevens parseren. Als in SleutelOfIndexOfPad
een bestaand element is opgegeven, wordt de waarde van dat element gewijzigd. Als het element niet bestaat, wordt een nieuw element toegevoegd.
JSONSetElement stelt het opgegeven element in op de parameter waarde.
U kunt een willekeurige geldige JSON-waarde opgeven, gaande van een eenvoudige tekenreeks of een getal tot een complex object of een complexe array.
De parameter type
geeft het type gegevens in waarde
op zodat de JSON-parser strikte regels volgt wanneer elk gegevenstype wordt verwerkt. Raadpleeg JSONSetElement functie voor de ondersteunde gegevenstypen. Om gegevens in json
in te voegen die al zijn opgemaakt als een geldig JSON-element, stelt u type
in op JSONRaw
.
In het volgende voorbeeld worden de sleutel-waarde-paren voor een nieuw product toegevoegd aan een leeg JSON-object. Het nieuwe object wordt dan toegevoegd aan het einde van de productarray in de $$JSON-variabele (raadpleeg Voorbeeld van JSON-gegevens).
Variabele instellen [ $NewProduct ; Waarde:
JSONSetElement ( "{}" ;
[ "id" ; "FB4" ; JSONString ] ;
[ "naam" ; "Vanillecake" ; JSONString ] ;
[ "prijs" ; 17.5 ; JSONNumber ] ;
[ "voorraad" ; 12 ; JSONNumber ] ;
[ "categorie" ; "Cakes" ; JSONString ] ;
[ "speciaal" ; true ; JSONBoolean ]
) ]
Variabele instellen [ $NextIndex ; Waarde:
ValueCount (
JSONListKeys ( $$JSON ; "bakkerij.product" )
) ]
Variabele instellen [ $$JSON ; Waarde:
JSONSetElement (
$$JSON ; "bakkerij.product[" & $NextIndex & "]" ; $NewProduct ;
JSONObject
) ]
Een andere JSON-functie waarmee een JSON-element wordt gemaakt, is de JSONMakeArray functie. Hiermee wordt een lijst met waarden naar een JSON-array geconverteerd. Als u gegevens wilt accepteren die op verschillende manieren zijn opgemaakt, kunt u met deze functie het teken opgeven waarmee elke waarde wordt gescheiden en het JSON-gegevenstype dat u wilt gebruiken.
JSON-gegevenselementen verwijderen
Gebruik de JSONDeleteElement functie om een element te verwijderen. De parameters json
en SleutelOfIndexOfPad
werken in deze functie zoals beschreven in JSON-gegevens parseren. De parameter SleutelOfIndexOfPad
moet een bestaand element in json
opgeven.
In het volgende voorbeeld wordt het element verwijderd in de productarray waarvan de sleutel "id" de waarde "FB3" heeft in de $$JSON-variabele (raadpleeg Voorbeeld van JSON-gegevens).
Variabele instellen [ $ProductTelling ; Waarde:
ValueCount (
JSONListKeys ( $$JSON ; "bakkerij.product" )
) ]
Variabele instellen [ $i ; Waarde: 0 ]
If [ $ProductTelling > 0 ]
Loop [ Wissen: Altijd ]
Variabele instellen [ $ID ; Waarde:
JSONGetElement ( $$JSON ; "bakkerij.product[" & $i & "]id" ) ]
If [ $ID = "FB3" ]
Variabele instellen [ $$JSON ; Waarde:
JSONDeleteElement ( $$JSON ; "bakkerij.product[" & $i & "]" ) ]
Script afsluiten [ Tekstresultaat: 0 ]
End If
Variabele instellen [ $i ; Waarde: $i + 1 ]
Exit Loop If [ $i ≥ $ProductTelling ]
End Loop
End If
JSON-prestaties optimaliseren
Wanneer een JSON-functie tekstinvoer parseert, maakt de JSON-parser een binaire weergave (geen tekstweergave) van de invoer om de verwerking van JSON later te versnellen. Er is een automatisch mechanisme om JSON te parseren en te cachen en dit is een expliciet mechanisme: de JSONParse functie.
Gebruikmaken van automatische JSON-caching
Parseren kost tijd, dus de JSON-functies cachen de binaire weergave van de laatst geparseerde JSON in het geheugen. Dit vermindert de noodzaak om dezelfde JSON later opnieuw te parseren. Er wordt slechts één automatische cache bijgehouden. Wanneer een andere JSON-waarde wordt geparseerd, wordt de eerder opgeslagen JSON-waarde genegeerd. De geparseerde JSON bestaat alleen in het geheugen—in variabelen, scriptparameters en berekeningen. Wanneer u de waarde van een veld instelt, wordt dit als tekst in het veld opgeslagen.
Op regelnummer geeft dit voorbeeld aan wanneer de JSON-tekst die oorspronkelijk is opgeslagen in $JSON1 en $JSON2 wordt geparseerd en wanneer dat niet het geval is.
Set Variable [ $id ; JSONGetElement ( $JSON1 ; "id" ) ]
Variabele instellen [ $name ; JSONGetElement ( $JSON1 ; "name" ) ]
Variabele instellen [ $price ; JSONGetElement ( $JSON2 ; "price" ) ]
Variabele instellen [ $category ; JSONGetElement ( $JSON1 ; "category" ) ]
-
$JSON1 wordt geparseerd en de binaire weergave wordt opgeslagen in de cache.
-
$JSON1 hoeft niet opnieuw geparseerd te worden.
-
$JSON2 wordt geparseerd en in de cache opgeslagen, waardoor de eerder opgeslagen waarde wordt vervangen.
-
$JSON1 wordt opnieuw geparseerd omdat het niet langer in de cache is opgeslagen.
Dus om te profiteren van automatische caching, is het het beste om te werken met één JSON-waarde per keer (in het bovenstaande voorbeeld, wissel regel 3 en 4 om om te voorkomen dat $JSON1 opnieuw wordt geparseerd).
JSONParse gebruiken
Gebruik de JSONParse functie om de binaire weergave van een JSON-waarde in een variabele en in de automatische cache te parseren en expliciet op te slaan. De parameter json
van de functie is een tekstexpressie die de evaluatie van JSON-gegevens uitvoert, of het nu gaat om tekst die is opgemaakt als JSON in een veld of een tekenreeks, of om tekst die al als JSON in een variabele is geparseerd.
In het volgende voorbeeld wordt JSON-tekst geparseerd:
Variabele instellen [ $JSON1 ; "{ \"product\": {\"id\": \"FB1\"} }" ]
Variabele instellen [ $JSON1 ; JSONParse ( $JSON1 ) ]
-
$JSON1 is alleen de tekstweergave, die er als volgt uitziet:
{ "product": {"id": "FB1"} }
-
Na gebruik van JSONParse:
-
De automatische cache bevat de binaire weergave.
-
De variabele $JSON1 bevat zowel de tekst als de binaire weergave.
-
Als JSONParse niet wordt gebruikt, dan geldt in dit voorbeeld het volgende:
Variabele instellen [ $JSON1 ; "{ \"product\": {\"id\": \"FB1\"} }" ]
Variabele instellen [ $JSON2 ; JSONGetElement ( $JSON1 ; "product") ]
-
$JSON1 is alleen de tekstweergave, zoals voorheen.
-
Na gebruik van JSONGetElement:
-
De automatische cache bevat de binaire weergave.
-
$JSON2 bevat de binaire weergave van
{"id": "FB1"}
. -
$JSON1 is nog steeds alleen de tekstweergave. De tekst is geparseerd, maar de binaire weergave bevindt zich alleen in de automatische cache.
-
Vergelijk dat met wat er gebeurt als u JSONParse toevoegt:
Variabele instellen [ $JSON1 ; "{ \"product\": {\"id\": \"FB1\"} }" ]
Variabele instellen [ $JSON1 ; JSONParse ( $JSON1 ) ]
Variabele instellen [ $JSON2 ; JSONGetElement ( $JSON1 ; "product") ]
-
$JSON1 is alleen de tekstweergave, zoals voorheen.
-
Na gebruik van JSONParse:
-
De automatische cache bevat de binaire weergave.
-
$JSON1 bevat zowel de tekstweergave als de binaire weergave.
-
-
Na gebruik van JSONGetElement:
-
$JSON2 bevat de binaire weergave van
{"id": "FB1"}
.De tekstweergave wordt op dit moment niet opgeslagen in $JSON2, maar wordt pas later gegenereerd wanneer dat nodig is.
-
Houd er rekening mee dat JSONGetElement $JSON1 in regel 3 niet hoefde te parseren, omdat het de binaire representatie kan gebruiken die is gecached met $JSON1 in regel 2.
Net zoals het parseren van tekst om een binaire weergave te krijgen, tijd kost, geldt dit ook voor het omzetten van binaire JSON naar tekst. Daarom is het resultaat van JSON-functies als JSONGetElement en JSONSetElement slechts de binaire weergave. De tekstweergave wordt alleen gemaakt wanneer dat nodig is, bijvoorbeeld wanneer een variabele (zoals $JSON2) in een veld wordt opgeslagen of wanneer een variabele wordt weergegeven in Gegevensinzage.
U kunt de Companion-functie JSONParsedState gebruiken om te zien of een gegeven JSON-waarde hiermee is geparseerd, of de JSON geldig is en wat het JSON-type is.
Aanbevolen procedures
Wanneer grote JSON-structuren herhaaldelijk worden verwerkt (vooral in lussen) of wanneer er met meerdere elementen in JSON-gegevens wordt gewerkt, kan de volgorde van bewerkingen een aanzienlijk verschil in prestaties maken.
Als u wilt profiteren van automatische JSON-caching, kunt u het beste niet wisselen tussen het laden van JSON-gegevens van het ene veld om aan te werken, overschakelen naar een ander veld om aan te werken en teruggaan naar het eerste veld. Telkens wanneer een JSON-functie verschillende JSON-tekst verwerkt, wordt de eerder opgeslagen JSON-tekst verwijderd, zodat de tekst opnieuw moet worden geparseerd. Dit levert bijvoorbeeld de langzaamste prestaties op:
# Voorbeeld - Niet efficiënt
Variabele instellen [ $namel ; Waarde: JSONGetElement ( Table::JSON1 ; "name" ) ]
Variabele instellen [ $name2 ; Waarde: JSONGetElement ( Table::JSON2 ; "name" ) ]
Variabele instellen [ $id1 ; Waarde: JSONGetElement ( Table::JSON1 ; "id" ) ]
Variabele instellen [ $id2 ; Waarde: JSONGetElement ( Table::JSON2 ; "id" ) ]
Door de stappen alleen opnieuw te ordenen zodat u al het werk aan dezelfde JSON-gegevens doet voordat u aan andere JSON-gegevens werkt, werkt de automatische cache in uw voordeel, waardoor u de gegevens uit hetzelfde veld niet tweemaal hoeft te parseren.
# Voorbeeld - Beter
Variabele instellen [ $namel ; Waarde: JSONGetElement ( Table::JSON1 ; "name" ) ]
Variabele instellen [ $id1 ; Waarde: JSONGetElement ( Table::JSON1 ; "id" ) ]
Variabele instellen [ $name2 ; Waarde: JSONGetElement ( Table::JSON2 ; "name" ) ]
Variabele instellen [ $id2 ; Waarde: JSONGetElement ( Table::JSON2 ; "id" ) ]
De beste en meest flexibele methode is om de JSONParse-functie te gebruiken om de JSON-tekst uit elke bron te halen, te parseren en op te slaan in een variabele. Op deze manier wordt het maar één keer geparseerd. Dan maakt het niet uit in welke volgorde u verdere bewerkingen uitvoert (zoals het ophalen of instellen van elementen), aangezien die JSON-functies de variabelen kunnen gebruiken, die de reeds geparseerde binaire weergaven bevatten.
{# Voorbeeld - Beste
Variabele instellen [ $JSON1 ; Waarde: JSONParse ( Table::JSON1 ) ]
Variabele instellen [ $JSON2 ; Waarde: JSONParse ( Table::JSON2 ) ]
Variabele instellen [ $namel ; Waarde: JSONGetElement ( $JSON1 ; "name" ) ]
Variabele instellen [ $name2 ; Waarde: JSONGetElement ( $JSON2 ; "name" ) ]
Variabele instellen [ $id1 ; Waarde: JSONGetElement ( $JSON1 ; "id" ) ]
Variabele instellen [ $id2 ; Waarde: JSONGetElement ( $JSON2 ; "id" ) ]
Fouten in JSON-gegevens verwerken
Als er een fout optreedt tijdens het parseren van de json
-parameter, geven de JSON-functies als resultaat "?" gevolgd door een foutbericht van de JSON-parser.
Wanneer bijvoorbeeld ":" na de sleutel "bakkerij" ontbreekt in Voorbeeld van JSON-gegevens, geeft deze berekening
JSONGetElement ( $$JSON ; "bakkerij.product[0]id" )
dit foutbericht als resultaat:
? * Regel 3, Kolom 2
Ontbrekende ':' na objectlidnaam
* Regel 13, Kolom 5
Extra non-whitespace na JSON-waarde.
Om te bepalen of JSON-gegevens geldig zijn alvorens ze te gebruiken, gebruikt u de JSONFormatElements functie en test u of het eerste teken "?" is. Bijvoorbeeld:
Variabele instellen [ $resultaat ; Waarde: JSONFormatElements ( $$JSON ) ]
If [ Left ( $resultaat ; 1 ) = "?" ]
# $$JSON bevat ongeldige JSON-gegevens.
End If
U kunt ook de JSONGetElementType functie gebruiken om te bepalen of JSON-gegevens geldig zijn en een specifiek JSON-type voordat u het gaat gebruiken. U kunt bijvoorbeeld als volgt testen of $$JSON een geldig JSON-object is:
Variabele instellen [ $resultaat ; Waarde: JSONGetElementType( $$JSON, "" ) ]
If [ $resultaat ≠ JSONObject ]
# $$JSON bevat ongeldige JSON-gegevens.
End If
Een andere manier om fouten op te sporen is met de JSONParsedState functie. Hiermee kunt u zien of de JSON-gegevens zijn geparseerd en geldig zijn, en zo ja, welk type JSON-gegevens het zijn.
Variabele instellen [ $Result ; Waarde: JSONParse ( $$JSON ) ]
Variabele instellen [ $ParsedState ; Waarde: JSONParsedState ( $result ) ]
If [ $ParsedState < 0 ]
# $$JSON is geparseerd maar bevat ongeldige JSON-gegevens.
Else If [ $ParsedState = 0 ]
# $$JSON is niet geparseerd.
Else If [ $ParsedState > 0 ]
# $$JSON is geparseerd en is geldig. $ParsedState geeft het JSON-type aan.
Variabele instellen [ $type ; Waarde:
Case (
$ParsedState = JSONString ; "JSON-type is JSONString" ;
$ParsedState = JSONNumber ; "JSON-type is JSONNumber" ;
$ParsedState = JSONObject ; "JSON-type is JSONObject" ;
$ParsedState = JSONArray ; "JSON-type is JSONArray" ;
$ParsedState = JSONBoolean ; "JSON-type is JSONBoolean" ;
$ParsedState = JSONNull ; "JSON-type is JSONNull"
)
]
Aangepast dialoogvenster tonen [ $type ]
End If
Voorbeeld van JSON-gegevens
In het volgende voorbeeld bevatten de JSON-gegevens het object "Bakkerij" dat een array van drie "product"-objecten heeft, elk met verschillende sleutel-waarde-paren.
{
"bakkerij" :
{
"product" :
[
{
"id" : "FB1",
"naam" : "Donuts",
"prijs" : 1.99,
"voorraad" : 43,
"categorie" : "Broden",
"speciaal" : true
},
{
"id" : "FB2",
"prijs" : 22.5,
"naam" : "Chocoladecake",
"voorraad" : 23,
"categorie" : "Cakes",
"speciaal" : true
},
{
"id" : "FB3",
"prijs" : 3.95,
"naam" : "Stokbrood",
"voorraad" : 34,
"categorie" : "Broden",
"speciaal" : true
}
]
}
}
Opmerkingen
De JSON-parser behoudt de volgorde van elementen in een array maar niet de volgorde van elementen in een object. Daarom kunnen JSON-functies elementen in een object in een andere volgorde dan de opgegeven volgorde geven.
In JSON-gegevens moet in breuken een punt "." worden gebruikt als het decimaalteken, ongeacht het scheidingsteken dat is opgegeven in de systeeminstellingen van uw computer of de instellingen die zijn gebruikt bij het maken van het FileMaker Pro-bestand.