Arbeiten mit den JSON-Funktionen
FileMaker Pro bietet mehrere Textfunktionen, mit denen Ihre eigene App JSON-Daten aus anderen FileMaker-Funktionen oder aus anderen Quellen, z. B. Webdiensten, die Daten im JSON-Format über eine REST-API übertragen, parsen (analysieren) und ändern kann.
Weitere Informationen über das JSON-Datenformat finden Sie unter json.org.
Die in diesem Thema gezeigten Beispiele verwenden JSON-Daten einer Bäckerei, die ihre Produktliste über eine REST-API im JSON-Format für Clients verfügbar macht. Folgendes gibt die Liste der heutigen Angebote als JSON-Daten in der Variablen $$JSON zurück:
Variable setzen [ $url ; "https://bäckerei.beispiel.de/rest/api/produkte" ]
Aus URL einfügen [ Mit Dialog: Aus; Ziel: $$JSON ; $url ; SSL-Zertifikate verifizieren ; cURL-Optionen: "--data list=Angebote" ]
Informationen zu den in $$JSON zurückgegebenen und in diesen Beispielen verwendeten Daten finden Sie unter Beispiel für JSON-Daten.
Formatieren von JSON-Daten
JSON-Daten benötigen keine Leerzeichen oder Zeilenenden zwischen Elementen. Damit Sie die Daten jedoch beim Beheben von Problemen besser lesen können, verwenden Sie die Funktion „JSONFormatElements“, die Tabulator- und Zeilenendezeichen hinzufügt, wie unter Beispiel für JSON-Daten gezeigt.
Parsen von JSON-Daten
Verwenden Sie die folgenden JSON-Funktionen, um JSON-Daten zu parsen, d. h. Schlüssel, Werte oder ganze JSON-Objekte oder -Arrays zu erhalten, die Sie weiter verarbeiten können:
-
JSONGetElement – Fragt JSON-Daten auf ein Element (Objekt, Array oder Wert) ab
-
JSONListKeys – Listet Objektnamen (Schlüssel) oder Array-Indizes in JSON-Daten auf
-
JSONListValues – Listet die Werte in JSON-Daten auf
Der erste Parameter dieser Funktionen, json
, gibt das Textfeld, die Variable oder den Textausdruck mit den gültigen JSON-Daten für die Bearbeitung an.
Der zweite Parameter, SchlüsselOderIndexOderPfad
, gibt den zu bearbeitenden Teil der JSON-Daten an:
-
Schlüssel – Name eines Schlüssels in einem JSON-Objekt
-
Index – Index eines Elements in einem JSON-Array (das erste Element hat den Index 0)
-
Pfad – hierarchische Zeichenfolge aus Schlüsselnamen bzw. Array-Indizes
Die folgenden zwei Syntaxtypen für den Parameter SchlüsselOderIndexOderPfad
werden unterstützt: Punktschreibweise und Klammerschreibweise.
Syntax für |
Erläuterung |
|
Punktschreibweise | Klammerschreibweise | |
---|---|---|
|
|
Die Root-Ebene, wenn es das erste Zeichen ist (optional bei der Punktschreibweise) |
|
|
Elemente bei Index n eines Arrays auf der Root-Ebene |
|
|
Der Schlüssel eines Objekts mit dem Namen name auf der Root-Ebene |
|
|
Ein Objekt mit dem Namen nameC, das ein Abkömmling von nameB und nameA ist |
|
|
Das erste Element des Arrays im Objekt nameA, das sich auf der dritten Ebene einer Gruppe von verschachtelten Arrays befindet |
|
|
Das letzte Element eines Arrays |
|
|
Die Position nach dem letzten Element eines Arrays. Wird in der Funktion „JSONSetElement“ verwendet, um ein Element am Ende eines Arrays hinzuzufügen. |
Der Unterschied zwischen Punkt- und Klammerschreibweise besteht darin, dass bei der Klammerschreibweise die Schlüsselnamen mit einfachen Anführungszeichen ('
) und Klammern ([]
) umgeben werden, anstatt Punkte (.
) zur Trennung zu verwenden. Sie können beide Schreibweisen in SchlüsselOderIndexOderPfad
verwenden. Sie müssen jedoch die Klammerschreibweise verwenden, wenn Schlüsselnamen Punkte enthalten, damit der JSON-Parser den gesamten Schlüsselnamen korrekt identifizieren kann. Wenn ein Schlüssel im Stamm eines JSON-Objekts z. B. „layout.response“
ist, dann wäre SchlüsselOderIndexOderPfad
„['layout.response']“
.
Das folgende Beispielscript erstellt einen Datensatz für jedes Produkt in einem JSON-Array. Unter der Annahme, dass die Beispiel für JSON-Daten in der Variablen $$JSON gespeichert sind, verwendet das Script JSONListValues, um den Inhalt des Produkt-Arrays als Liste von Werten abzurufen, und verwendet ElementeAnzahl, um die Anzahl der Produkte in der Liste zu bestimmen. Das Script erstellt jedes Mal, wenn es die Schleife durchläuft, einen Datensatz für ein Produkt und verwendet HoleWert, um das JSON-Objekt für ein Produkt aus der Liste zu abzurufen, und setzt die Felder auf die mit JSONGetElement erhaltenen Werte. Da die JSON-Funktionen das gesamte JSON-Objekt analysieren, das an sie übergeben wird, kann es effizienter sein, die JSON-Funktionen auf kleinere JSON-Objekte innerhalb einer Schleife anzuwenden, die mehrmals wiederholt wird.
Variable setzen [ $Produktliste ; Wert: JSONListValues ( $$JSON ; "Baeckerei.Produkt" ) ]
Variable setzen [ $ProduktAnzahl ; Wert: ElementeAnzahl ( $Produktliste ) ]
Variable setzen [ $i; Wert: 1 ]
Wenn [ $ProduktAnzahl > 0 ]
Schleife (Anfang) [ Löschen: Immer ]
Neuer Datensatz/Abfrage
Variable setzen [ $Produkt ; Wert: HoleWert ( $Produktliste ; $i ) ]
Feldwert setzen [ Produkte::ID ; JSONGetElement ( $Produkt ; "id" ) ]
Feldwert setzen [ Produkte::Preis ; JSONGetElement ( $Produkt ; "Preis" ) ]
Feldwert setzen [ Produkte::Bestand ; JSONGetElement ( $Produkt ; "Bestand" ) ]
Schreibe Änderung Datens./Abfrage [ Mit Dialog: Aus ]
Variable setzen [ $i ; Wert: $i + 1 ]
Verlasse Schleife wenn [ $i > $ProduktAnzahl ]
Schleife (Ende)
Ende (wenn)
Ändern und Hinzufügen von JSON-Datenelementen
Verwenden Sie die Funktion „JSONSetElement“, um in JSON-Daten Werte zu ändern und Elemente hinzuzufügen. Die Parameter json
und SchlüsselOderIndexOderPfad
funktionieren hier so, wie unter Parsen von JSON-Daten beschrieben. Wenn SchlüsselOderIndexOderPfad
ein bestehendes Element angibt, wird der Wert dieses Elements geändert. Wenn das Element nicht existiert, wird es hinzugefügt.
JSONSetElement stellt das angegebene Element auf den Parameter Wert
ein. Sie können einen beliebigen gültigen JSON-Wert angeben, von einer einfachen Zeichenfolge oder Zahl bis zu einem komplexen Objekt oder Array.
Der Parameter Typ
gibt den Datentyp in Wert
an, damit der JSON-Parser beim Umgang mit jedem Datentyp strikte Regeln befolgt. Informationen über die unterstützten Datentypen finden Sie unter Funktion „JSONSetElement“. Um bereits als gültiges JSON-Element formatierte Daten in json
einzufügen, stellen Sie Typ
auf JSONRaw
ein.
Das folgende Beispiel fügt einem leeren JSON-Objekt die Schlüssel-Wert-Paare für ein neues Produkt hinzu. Das neue Objekt wird dann an das Ende des Produktarrays in der Variablen $$JSON hinzugefügt (siehe Beispiel für JSON-Daten).
Variable setzen [ $NeuesProdukt ; Wert:
JSONSetElement ( "{}" ;
[ "id" ; "LB4" ; JSONString ] ;
[ "Name" ; "Vanillekuchen" ; JSONString ] ;
[ "Preis" ; 17.5 ; JSONNumber ] ;
[ "Bestand" ; 12 ; JSONNumber ] ;
[ "Kategorie" ; "Kuchen" ; JSONString ] ;
[ "Angebot" ; true ; JSONBoolean ]
) ]
Variable setzen [ $NächsterIndex ; Wert:
ElementeAnzahl (
JSONListKeys ( $$JSON ; "Baeckerei.Produkt" )
) ]
Variable setzen [ $$JSON ; Wert:
JSONSetElement (
$$JSON ; "Baeckerei.Produkt[" & $NächsterIndex & "]" ; $NeuesProdukt ;
JSONObject
) ]
Eine weitere JSON-Funktion, die ein JSON-Element erstellt, ist die Funktion „JSONMakeArray“. Sie konvertiert eine Liste von Werten in ein JSON-Array. Um unterschiedlich formatierte Daten zu akzeptieren, können Sie mit dieser Funktion das Zeichen angeben, das die Werte voneinander trennt, und den zu verwendenden JSON-Datentyp.
Löschen von JSON-Datenelementen
Verwenden Sie die Funktion „JSONDeleteElement“, um ein Element zu löschen. Die Parameter json
und SchlüsselOderIndexOderPfad
funktionieren hier so, wie unter Parsen von JSON-Daten beschrieben. Der Parameter SchlüsselOderIndexOderPfad
muss ein bestehendes Element in json
angeben.
Das folgende Beispiel löscht das Element im Produktarray, dessen „ID“-Schlüssel in der $$JSON-Variablen den Wert LB3 hat (siehe Beispiel für JSON-Daten).
Variable setzen [ $ProduktAnzahl ; Wert:
ElementeAnzahl (
JSONListKeys ( $$JSON ; "Baeckerei.Produkt" )
) ]
Variable setzen [ $i ; Wert: 0 ]
Wenn [ $ProduktAnzahl > 0 ]
Schleife (Anfang) [ Löschen: Immer ]
Variable setzen [ $ID ; Wert:
JSONGetElement ( $$JSON ; "Baeckerei.Produkt[" & $i & "]id" ) ]
Wenn [ $ID = "LB3" ]
Variable setzen [ $$JSON ; Wert:
JSONDeleteElement ( $$JSON ; "Baeckerei.Produkt[" & $i & "]" ) ]
Aktuelles Script verlassen [ Textergebnis: 0 ]
Ende (wenn)
Variable setzen [ $i ; Wert: $i + 1 ]
Verlasse Schleife wenn [ $i > $ProduktAnzahl ]
Schleife (Ende)
Ende (wenn)
Optimieren der JSON-Leistung
Immer wenn eine JSON-Funktion eine Texteingabe parst, erstellt der JSON-Parser eine binäre (keine Text-)Darstellung davon, um die spätere Verarbeitung des JSON zu beschleunigen. Es gibt einen automatischen Mechanismus zum Parsen und Zwischenspeichern von JSON und einen expliziten Mechanismus: die Funktion „JSONParse“.
Nutzung des automatischen JSON-Caching
Das Parsen nimmt Zeit in Anspruch, daher speichern die JSON-Funktionen die binäre Darstellung des zuletzt geparsten JSON in einem Zwischenspeicher. Dadurch muss derselbe JSON später nicht erneut geparst werden. Es wird nur ein automatischer Cache verwaltet. Wenn ein anderer JSON-Wert geparst wird, wird der zuvor zwischengespeicherte JSON-Wert verworfen. Der geparste JSON existiert nur im Arbeitsspeicher – in Variablen, Scriptparametern und Formeln. Wenn er zum Setzen des Feldwerts verwendet wird, wird er als Text im Feld gespeichert.
Anhand der Zeilennummern zeigt dieses Beispiel, wann der ursprünglich in $JSON1 und $JSON2 gespeicherte JSON-Text geparst wird und wann nicht.
Variable setzen [ $id ; JSONGetElement ( $JSON1 ; "id" ) ]
Variable setzen [ $Name ; JSONGetElement ( $JSON1 ; "Name" ) ]
Variable setzen [ $Preis ; JSONGetElement ( $JSON2 ; "Preis" ) ]
Variable setzen [ $Kategorie ; JSONGetElement ( $JSON1 ; "Kategorie" ) ]
-
$JSON1 wird geparst und die binäre Darstellung wird im Cache zwischengespeichert.
-
$JSON1 muss nicht erneut geparst werden.
-
$JSON2 wird geparst und zwischengespeichert, wobei der zuvor zwischengespeicherte Wert ersetzt wird.
-
$JSON1 wird erneut geparst, da er nicht mehr im Cache gespeichert war.
Um die Vorteile des automatischen Cachings zu nutzen, sollten Sie daher jeweils nur mit einem JSON-Wert arbeiten (im obigen Beispiel tauschen Sie die Zeilen 3 und 4, um ein erneutes Parsen von $JSON1 zu vermeiden).
Verwenden von JSONParse
Um die binäre Darstellung eines JSON-Werts zu parsen und explizit in einer Variablen sowie im automatischen Cache zu speichern, verwenden Sie die Funktion „JSONParse“. Der Parameter json
der Funktion ist ein beliebiger Textausdruck, der zu JSON-Daten ausgewertet wird, unabhängig davon, ob es sich um Text handelt, der in einem Feld als JSON formatiert ist, um einen String oder um bereits geparste JSON-Daten in einer Variablen.
Das folgende Beispiel parst JSON-Text:
Variable setzen [ $JSON1 ; "{ \"Produkt\": {\"id\": \"LB1\"} }" ]
Variable setzen [ $JSON1 ; JSONParse( $JSON1 ) ]
-
$JSON1 ist nur die Textdarstellung, die wie folgt aussieht:
{ "Produkt": {"id": "LB1"} }
-
Nach Verwendung von JSONParse:
-
Der automatische Cache enthält die binäre Darstellung.
-
Die Variable $JSON1 enthält sowohl die Text- als auch die Binärdarstellung.
-
Wenn JSONParse nicht verwendet wird, dann gilt in dem nachstehenden Beispiel:
Variable setzen [ $JSON1 ; "{ \"Produkt\": {\"id\": \"LB1\"} }" ]
Variable setzen [ $JSON2 ; JSONGetElement ( $JSON1 ; "Produkt") ]
-
$JSON1 ist nur die Textdarstellung, wie zuvor.
-
Nach Verwendung von JSONGetElement:
-
Der automatische Cache enthält die Binärdarstellung.
-
$JSON2 enthält die binäre Darstellung von
{„id“: „LB1“}
. -
$JSON1 ist weiterhin nur die Textdarstellung. Der Text wurde geparst, aber die Binärdarstellung befindet sich nur im automatischen Cache.
-
Vergleichen Sie dies mit dem, was passiert, wenn Sie JSONParse hinzufügen:
Variable setzen [ $JSON1 ; "{ \"Produkt\": {\"id\": \"LB1\"} }" ]
Variable setzen [ $JSON1 ; JSONParse ( $JSON1 ) ]
Variable setzen [ $JSON2 ; JSONGetElement ( $JSON1 ; "Produkt") ]
-
$JSON1 ist nur die Textdarstellung, wie zuvor.
-
Nach Verwendung von JSONParse:
-
Der automatische Cache enthält die Binärdarstellung.
-
$JSON1 enthält sowohl die Text- als auch die Binärdarstellung.
-
-
Nach Verwendung von JSONGetElement:
-
$JSON2 enthält die binäre Darstellung von
{„id“: „LB1“}
.Die Textdarstellung wird zu diesem Zeitpunkt noch nicht in $JSON2 gespeichert, sondern erst später bei Bedarf generiert.
-
Beachten Sie, dass JSONGetElement in Zeile 3 $JSON1 nicht parsen musste, da es die in Zeile 2 mit $JSON1 zwischengespeicherte Binärdarstellung verwenden konnte.
Genauso wie das Parsen von Text, um eine Binärdarstellung zu erhalten, Zeit benötigt, dauert auch die Konvertierung von binärem JSON in Text einige Zeit. Aus diesem Grund ist das Ergebnis von JSON-Funktionen wie JSONGetElement und JSONSetElement nur die binäre Darstellung. Die Textdarstellung wird nur bei Bedarf erstellt, beispielsweise beim Speichern einer Variablen (wie $JSON2) in einem Feld oder beim Anzeigen einer Variablen in der Datenanzeige.
Mit der Begleitfunktion JSONParsedState können Sie feststellen, ob ein bestimmter JSON-Wert geparste JSON-Daten enthält, ob die JSON-Daten gültig sind und um welchen JSON-Typ es sich handelt.
Beste Verfahren
Bei der wiederholten Verarbeitung großer JSON-Strukturen (insbesondere in Schleifen) oder bei der Arbeit mit mehreren Elementen in JSON-Daten kann die Reihenfolge der Operationen einen erheblichen Einfluss auf die Leistung haben.
Um die Vorteile des automatischen JSON-Caching zu nutzen, sollten Sie nicht zwischen dem Laden von JSON-Daten aus einem Feld zum Bearbeiten, dem Wechseln zu einem anderen Feld zum Bearbeiten und dem Zurückkehren zum ersten Feld wechseln. Jedes Mal, wenn eine JSON-Funktion unterschiedlichen JSON-Text verarbeitet, wird der zuvor zwischengespeicherte JSON-Text verworfen, sodass der Text erneut geparst werden muss. Dies führt beispielsweise zu der langsamsten Leistung:
# Beispiel - Nicht effizient
Variable setzen [ $name1 ; Wert: JSONGetElement ( Tabelle::JSON1 ; "Name" ) ]
Variable setzen [ $name2 ; Wert: JSONGetElement ( Tabelle::JSON2 ; "Name" ) ]
Variable setzen [ $id1 ; Wert: JSONGetElement ( Tabelle::JSON1 ; "id" ) ]
Variable setzen [ $id2 ; Wert: JSONGetElement ( Tabelle::JSON2 ; "id" ) ]
Indem Sie lediglich die Schritte so umordnen, dass Sie alle Arbeiten an denselben JSON-Daten ausführen, bevor Sie mit anderen JSON-Daten arbeiten, nutzen Sie den automatischen Cache zu Ihrem Vorteil und müssen die Daten aus demselben Feld nicht zweimal parsen.
# Beispiel – Besser
Variable setzen [ $name1 ; Wert: JSONGetElement ( Tabelle::JSON1 ; "Name" ) ]
Variable setzen [ $id1 ; Wert: JSONGetElement ( Tabelle::JSON1 ; "id" ) ]
Variable setzen [ $name2 ; Wert: JSONGetElement ( Tabelle::JSON2 ; "Name" ) ]
Variable setzen [ $id2 ; Wert: JSONGetElement ( Tabelle::JSON2 ; "id" ) ]
Die beste und flexibelste Methode ist die Verwendung der Funktion „JSONParse“, um den JSON-Text aus jeder Quelle abzurufen, zu analysieren und in einer Variablen zu speichern. Auf diese Weise wird er nur einmal geparst. Dann spielt es keine Rolle, in welcher Reihenfolge Sie weitere Operationen (wie das Abrufen oder Setzen von Elementen) durchführen, da diese JSON-Funktionen die Variablen verwenden können, die die bereits geparsten binären Darstellungen enthalten.
# Beispiel – Am besten
Variable setzen [ $JSON1 ; Wert: JSONParse ( Tabelle::JSON1 ) ]
Variable setzen [ $JSON2 ; Wert: JSONParse ( Tabelle::JSON2 ) ]
Variable setzen [ $name1 ; Wert: JSONGetElement ( $JSON1 ; "Name" ) ]
Variable setzen [ $name2 ; Wert: JSONGetElement ( $JSON2 ; "Name" ) ]
Variable setzen [ $id1 ; Wert: JSONGetElement ( $JSON1 ; "id" ) ]
Variable setzen [ $id2 ; Wert: JSONGetElement ( $JSON2 ; "id" ) ]
Behandlung von Fehlern in JSON-Daten
Wenn beim Parsen des Parameters json
ein Fehler auftritt, liefert die Funktion JSON ein „?“ gefolgt von einer Fehlermeldung aus dem JSON-Parser.
Wenn beispielsweise der „:“ nach dem Schlüssel „Baeckerei“ in Beispiel für JSON-Daten fehlt, gibt diese Formel
JSONGetElement ( $$JSON ; "Baeckerei.Produkt[0]id" )
diese Fehlermeldung zurück:
? * Line 3, Column 2
Missing ':' after object member name
* Line 13, Column 5
Extra non-whitespace after JSON value.
Anhand der Funktion „JSONFormatElements“ können Sie feststellen, ob JSON-Daten gültig sind, und testen, ob das erste Zeichen ein „?“ ist. Beispiel:
Variable setzen [ $Ergebnis ; Wert: JSONFormatElements ( $$JSON ) ]
Wenn [ Links ( $Ergebnis ; 1 ) = "?" ]
# $$JSON enthält ungültige JSON-Daten.
Ende (wenn)
Alternativ können Sie vor der Verwendung von JSON-Daten mit der Funktion „JSONGetElementType“ überprüfen, ob diese gültig sind und einem bestimmten JSON-Typ entsprechen. Um beispielsweise zu testen, ob $$JSON ein gültiges JSON-Objekt ist, verwenden Sie folgenden Code:
Variable setzen [ $Ergebnis ; Wert: JSONGetElementType( $$JSON, "" ) ]
Wenn [ $Ergebnis ≠ JSONObject ]
# $$JSON enthält ungültige JSON-Daten.
Ende (wenn)
Eine weitere Möglichkeit zum Erkennen von Fehlern bietet die Funktion „JSONParsedState“. Sie gibt Auskunft darüber, ob die JSON-Daten geparst wurden und gültig sind und, falls ja, um welchen JSON-Datentyp es sich handelt.
Variable setzen [ $Ergebnis; Wert: JSONParse ( $$JSON ) ]
Variable setzen [ $ParsedState ; Wert: JSONParsedState ( $Ergebnis) ]
Wenn [ $ParsedState < 0 ]
# $$JSON wurde geparst, enthält jedoch ungültige JSON-Daten.
Sonst, wenn [ $ParsedState = 0 ]
# $$JSON wurde nicht geparst.
Sonst, wenn [ $ParsedState > 0 ]
# $$JSON wurde geparst und ist gültig. $ParsedState gibt den JSON-Typ an.
Variable setzen [ $Typ ; Wert:
Falls (
$ParsedState = JSONString ; "JSON-Typ ist JSONString" ;
$ParsedState = JSONNumber ; "JSON-Typ ist JSONNumber" ;
$ParsedState = JSONObject ; "JSON-Typ ist JSONObject" ;
$ParsedState = JSONArray ; "JSON-Typ ist JSONArray" ;
$ParsedState = JSONBoolean ; "JSON-Typ ist JSONBoolean" ;
$ParsedState = JSONNull ; "JJSON-Typ ist JSONNull"
)
]
Eigenes Dialogfeld anzeigen [ $Typ ]
Ende (wenn)
Beispiel für JSON-Daten
Im folgenden Beispiel enthalten JSON-Daten ein „Baeckerei“-Objekt mit einem Array von drei „Produkt“-Objekten, jedes mit mehreren Schlüssel-Wert-Paaren.
{
"Baeckerei" :
{
"Produkt" :
[
{
"id" : "LB1",
"Name" : "Donuts",
"Preis": 1.99,
"Bestand" : 43,
"Kategorie" : "Brot",
"Angebot" : true
},
{
"id" : "LB2",
"Preis": 22.5,
"Name" : "Schokoladenkuchen",
"Bestand" : 23,
"Kategorie" : "Kuchen",
"Angebot" : true
},
{
"id" : "LB3",
"Preis": 3.95,
"Name" : "Baguette",
"Bestand" : 34,
"Kategorie" : "Brot",
"Angebot" : true
}
]
}
}
Hinweise
-
Der JSON-Parser bewahrt die Reihenfolge der Elemente in einem Array, aber nicht die Reihenfolge der Elemente in einem Objekt. Daher können die JSON-Funktionen Elemente in einem Objekt in einer anderen als der angegebenen Reihenfolge zurückgeben.
-
In JSON-Daten müssen gebrochene Zahlenwerte einen Punkt „.“ als Dezimaltrennzeichen verwenden, unabhängig davon, welches Trennzeichen durch die Systemformate Ihres Computers oder die beim Erstellen der FileMaker Pro-Datei verwendeten Formate angegeben wird.