Utilisation des fonctions JSON

FileMaker Pro fournit plusieurs fonctions texte permettant à votre app personnalisée d'analyser et de modifier les données JSON à partir d'autres fonctions FileMaker ou d'autres sources, tels que les services Web qui transfèrent les données au format JSON via une API REST.

Pour plus d'informations sur le format de données JSON, consultez le site Web json.org.

Les exemples présentés dans cette rubrique utilisent les données JSON d'une boulangerie qui met sa liste de produits à la disposition des clients au format JSON via une API REST. L'exemple suivant renvoie la liste des offres spéciales du jour sous forme de données JSON dans la variable $$JSON :

Copier
Définir variable [ $url ; "https://boulangerie.exemple.com/rest/api/products" ]
Copier
Insérer depuis URL [ Avec boîte de dialogue: Non ; Cible: $$JSON ; $url ; Vérifier les certificats SSL ; options cURL: "--data liste=offres spéciales" ]

Pour les données renvoyées dans $$JSON et utilisées dans ces exemples, consultez la section Exemple de données JSON.

Mise en forme de données JSON

Les données JSON ne nécessitent pas d'espace ou de fin de ligne entre les éléments. Cependant, pour faciliter la lecture des données lors de la résolution de problèmes, utilisez la fonction JSONFormatElements, qui ajoute des tabulations et des caractères de fin de ligne, tel qu'indiqué dans la section Exemple de données JSON.

Analyse de données JSON

Les fonctions JSON suivantes vous permettent d'analyser des données JSON, notamment d'obtenir des clés, des valeurs, des tableaux ou des objets JSON entiers pour un traitement supplémentaire :

  • JSONGetElement : interroge les données JSON à propos d'un élément (objet, tableau ou valeur).

  • JSONListKeys : répertorie les noms d'objet (clés) ou index de tableau dans les données JSON.

  • JSONListValues : répertorie les valeurs dans les données JSON.

Le premier paramètre de ces fonctions, json, spécifie la rubrique Texte, la variable ou l'expression de type texte contenant les données JSON valides sur lesquelles agir.

Le second paramètre, cléOuIndexOuChemin, spécifie la partie des données JSON sur lesquelles agir.

  • clé : nom d'une clé dans un objet JSON.

  • index : index d'un élément dans un tableau JSON (le premier élément a un index de 0).

  • chemin d'accès : chaîne hiérarchique de noms de clé et/ou d'index de tableau

Les deux types de syntaxe suivants sont pris en charge pour le paramètre cléOuIndexOuChemin : notation par points et notation par crochets.

Syntaxe du paramètre cléOuIndexOuChemin

Désigne

Notation par points Notation par crochets

"."

""

Le niveau racine, s'il s'agit du premier caractère (facultatif dans la notation par points)

".[n]"

"[n]"

Les éléments à l'index n d'un tableau au niveau racine

".nom"

"['nom']"

La clé d'un objet nommé nom au niveau racine

".nomA.nomB.nomC"

"['nomA']['nomB']['nomC']"

Un objet nommé nomC, qui est un descendant de nomB et nomA

".[3][2][1]nomA[0]"

"[3][2][1]['nomA'][0]"

Le premier élément du tableau dans l'objet nomA, qui est au troisième niveau dans un ensemble de tableaux imbriqués.

"[:]"

"[:]"

Le dernier élément d'un tableau

"[+]"

"[+]"

La position après le dernier élément d'un tableau. Utilisé dans la fonction JSONSetElement pour ajouter un élément à la fin d'un tableau.

La différence entre la notation par points et par crochets est qu'au lieu d'utiliser des points (.) pour séparer les noms des clés, la notation par crochets entoure les noms de clés avec des guillemets simples (') et des crochets ([]). Vous pouvez utiliser l'une ou l'autre dans le paramètre cléOuIndexOuChemin. Toutefois, vous devez utiliser la notation par crochets si les noms de clé incluent des points, afin que l'analyseur JSON puisse correctement identifier le nom de la clé. Par exemple, si une clé à la racine d'un objet JSON est « modèle.réponse », alors le paramètre cléOuIndexOuChemin est « ['modèle.réponse'] ».

L'exemple de script suivant crée un enregistrement pour chaque produit dans un tableau JSON. En supposant que l'Exemple de données JSON soit stocké dans la variable $$JSON, le script utilise JSONListValues pour obtenir le contenu du tableau de produits sous la forme d'une liste de valeurs et utilise DecompteValeurs pour déterminer le nombre de produits figurant dans la liste. En enregistrant systématiquement un produit dans la boucle, le script utilise ObtenirValeur pour obtenir l'objet JSON d'un produit dans la liste et configure les rubriques en utilisant les valeurs obtenues à l'aide de JSONGetElement. Étant donné que les fonctions JSON analysent intégralement l'objet JSON qui leur a été transmis, il est recommandé d'utiliser les fonctions JSON sur des objets JSON plus petits figurant dans une boucle répétée plusieurs fois.

Copier
Définir variable [ $ProductList ; Valeur: JSONListValues ( $$JSON ; "boulangerie.produit" ) ]
Définir variable [ $ProductCount ; Valeur: DecompteValeurs ( $ProductList ) ]
Définir variable [ $i ; Valeur: 1 ]
Si [ $ProductCount > 0 ]
   Boucle [ Purge: Systématique ]
      Nouvel enreg./requête
      Définir variable [ $Product ; Valeur: ObtenirValeur ( $ProductList ; $i ) ]
      Définir rubrique [ Produits::Identifiant ; JSONGetElement ( $Product ; "id" ) ]
      Définir rubrique [ Produits::Prix ; JSONGetElement ( $Product ; "prix" ) ]
      Définir rubrique [ Produits::Stock ; JSONGetElement ( $Product ; "stock" ) ]
      Valider enreg./requêtes [ Avec boîte de dialogue: Non ]
      Définir variable [ $i ; Valeur: $i + 1 ] 
      Fin de boucle si [ $i > $ProductCount ]
   Fin de boucle
Fin de si

Modification et ajout d'éléments de données JSON

La fonction JSONSetElement vous permet de modifier des valeurs et d'ajouter des éléments dans les données JSON. Les paramètres json et cléOuIndexOuChemin fonctionnent au sein de cette fonction, tel que décrit dans la section Analyse de données JSON. Si le paramètre cléOuIndexOuChemin spécifie un élément existant, la valeur de cet élément est modifiée ; si l'élément n'existe pas, un nouvel élément est ajouté.

La fonction JSONSetElement définit l'élément spécifié sur le paramètre valeur. Vous pouvez spécifier n'importe quelle valeur JSON valide, allant d'un simple nombre ou chaîne à un objet ou un tableau complexe.

Le paramètre type spécifie le type de données du paramètre valeur de façon à ce que l'analyseur JSON suive des règles strictes lors de la gestion de chaque type de données. Pour connaître les types de données pris en charge, consultez la section fonction JSONSetElement. Pour insérer des données dans le paramètre json déjà mis en forme comme élément JSON valide, définissez le paramètre type sur JSONRaw.

L'exemple suivant ajoute des paires clé-valeur pour un nouveau produit à un objet JSON vide. Ensuite, le nouvel objet est ajouté à la fin du tableau de produits dans la variable $$JSON (consultez la section Exemple de données JSON).

Copier
Définir variable [ $NewProduct ; Valeur: 
   JSONSetElement ( "{}" ;
      [ "id" ; "FB4" ; JSONString ] ; 
      [ "nom" ; "Gâteau à la vanille" ; JSONString ] ; 
      [ "prix" ; 17.5 ; JSONNumber ] ; 
      [ "stock" ; 12 ; JSONNumber ] ; 
      [ "catégorie" ; "Gâteaux" ; JSONString ] ; 
      [ "offre spéciale" ; true ; JSONBoolean ] 
   ) ]
Définir variable [ $NextIndex ; Valeur: 
   DecompteValeurs ( 
      JSONListKeys ( $$JSON ; "boulangerie.produit" ) 
   ) ] 
Définir variable [ $$JSON ; Valeur: 
   JSONSetElement ( 
      $$JSON ; "boulangerie.produit[" & $NextIndex & "]" ; $NewProduct ; 
      JSONObject 
   ) ]

Une autre fonction JSON qui crée un élément JSON est la fonction JSONMakeArray. Elle convertit une liste de valeurs en un tableau JSON. Pour accepter les données formatées de différentes manières, cette fonction vous permet de spécifier le caractère qui sépare chaque valeur et le type de données JSON à utiliser.

Suppression d'éléments de données JSON

La fonction JSONDeleteElement vous permet de supprimer un élément. Les paramètres json et cléOuIndexOuChemin fonctionnent au sein de cette fonction, tel que décrit dans la section Analyse de données JSON. Le paramètre cléOuIndexOuChemin doit spécifier un élément existant dans le paramètre json.

L'exemple suivant supprime l'élément dans le tableau de produits dont la clé « ID » a la valeur « FB3 » dans la variable $$JSON (consultez la section Exemple de données JSON).

Copier
Définir variable [ $ProductCount ; Valeur: 
   DecompteValeurs ( 
      JSONListKeys ( $$JSON ; "boulangerie.produit" ) 
   ) ] 
Définir variable [ $i ; Valeur: 0 ]
Si [ $ProductCount > 0 ]
   Boucle [ Purge: Systématique ]
      Définir variable [ $ID ; Valeur: 
         JSONGetElement ( $$JSON ; "boulangerie.produit[" & $i & "]id" ) ]
      Si [ $ID = "FB3" ]
         Définir variable [ $$JSON ; Valeur: 
            JSONDeleteElement ( $$JSON ; "boulangerie.produit[" & $i & "]" ) ]
         Fin de script [ Texte de résultat: 0 ]
      Fin de si
      Définir variable [ $i ; Valeur: $i + 1 ]
      Fin de boucle si [ $i ≥ $ProductCount ]
   Fin de boucle
Fin de si

Optimisation des performances JSON

Chaque fois qu'une fonction JSON analyse la saisie de texte, l'analyseur JSON en crée une représentation binaire (et non textuelle) pour accélérer le traitement JSON ultérieur. Il existe un mécanisme automatique pour analyser et mettre en cache le JSON et un mécanisme explicite : la fonction JSONParse.

Tirer parti de la mise en cache JSON automatique

L'analyse prenant un certain temps, les fonctions JSON mettent en cache la représentation binaire du dernier JSON analysé. Cela réduit le besoin d'analyser à nouveau le même JSON plus tard. Un seul cache automatique est entretenu. Lorsqu'une valeur JSON différente est analysée, la valeur JSON précédemment mise en cache est rejetée. Le JSON analysé n'existe qu'en mémoire (dans les variables, les paramètres de script et les calculs). Lorsqu'utilisé pour définir la valeur d'une rubrique, il est stocké dans la rubrique sous forme de texte.

Par numéro de ligne, cet exemple illustre quand le texte JSON initialement stocké dans $JSON1 et $JSON2 est analysé et quand il ne l'est pas.

Copier
Définir variable [ $id ; JSONGetElement ( $JSON1 ; "id" ) ]
Définir variable [ $nom ; JSONGetElement ( $JSON1 ; "nom" ) ]
Définir variable [ $prix ; JSONGetElement ( $JSON2 ; "prix" ) ]
Définir variable [ $catégorie ; JSONGetElement ( $JSON1 ; "catégorie" ) ]
  1. $JSON1 est analysé et la représentation binaire est enregistrée dans le cache.

  2. $JSON1 n'a pas besoin d'être à nouveau analysé.

  3. $JSON2 est analysé et mis en cache, remplaçant la valeur précédemment mise en cache.

  4. $JSON1 est à nouveau analysé parce qu'il n'était plus mis en cache.

Pour profiter de la mise en cache automatique, il est préférable de travailler avec une seule valeur JSON à la fois (dans l'exemple ci-dessus, échangez les lignes 3 et 4 pour éviter d'analyser à nouveau $JSON1).

Utilisation de JSONParse

Pour analyser et stocker explicitement la représentation binaire d'une valeur JSON dans une variable ainsi que dans le cache automatique, utilisez la fonction fonction JSONParse. Le paramètre json de la fonction correspond à toute expression de texte qui évalue les données JSON, qu'il s'agisse de texte formaté en JSON dans une rubrique ou une chaîne, ou d'un JSON déjà analysé dans une variable.

L'exemple suivant analyse le texte JSON :

Copier
Définir variable [ $JSON1 ; "{ \"produit\": {\"id\": \"FB1\"} }" ]
Définir variable [ $JSON1 ; JSONParse ( $JSON1 ) ]
  1. $JSON1 n'est que la représentation du texte, qui ressemble à ceci :

    { "produit": {"id": "FB1"} }

  2. Après avoir utilisé JSONParse :

    • Le cache automatique contient la représentation binaire.

    • La variable $JSON1 contient à la fois le texte et les représentations binaires.

Si JSONParse n'est pas utilisée, alors dans cet exemple :

Copier
Définir variable [ $JSON1 ; "{ \"produit\": {\"id\": \"FB1\"} }" ]
Définir variable [ $JSON2 ; JSONGetElement ( $JSON1 ; "produit" ) ]
  1. $JSON1 n'est que la représentation textuelle, comme avant.

  2. Après avoir utilisé JSONGetElement :

    • Le cache automatique contient la représentation binaire.

    • $JSON2 contient la représentation binaire de {"id": "FB1"}.

    • $JSON1 n'est toujours que la représentation du texte. Le texte a été analysé, mais la représentation binaire ne se trouve que dans le cache automatique.

Comparez cela à ce qui se passe lorsque vous ajoutez JSONParse :

Copier
Définir variable [ $JSON1 ; "{ \"produit\": {\"id\": \"FB1\"} }" ]
Définir variable [ $JSON1 ; JSONParse ( $JSON1 ) ]
Définir variable [ $JSON2 ; JSONGetElement ( $JSON1 ; "produit" ) ]
  1. $JSON1 n'est que la représentation textuelle, comme avant.

  2. Après avoir utilisé JSONParse :

    • Le cache automatique contient la représentation binaire.

    • $JSON1 contient à la fois le texte et les représentations binaires.

  3. Après avoir utilisé JSONGetElement :

    • $JSON2 contient la représentation binaire de {"id": "FB1"}.

      La représentation de texte n'est pas stockée dans $JSON2 à ce stade, mais n'est générée plus tard qu'en cas de besoin.

Notez que la fonction JSONGetElement n'avait pas besoin d'analyser $JSON1 à la ligne 3, car elle pouvait utiliser la représentation binaire mise en cache avec $JSON1 à la ligne 2.

Juste comme l'analyse du texte pour obtenir une représentation binaire, la conversion d'un JSON binaire en texte prend du temps. C'est pourquoi le résultat des fonctions JSON comme JSONGetElement et JSONSetElement n'est qu'une représentation binaire. La représentation textuelle n'est créée qu'en cas de besoin, par exemple lors du stockage d'une variable (comme $JSON2) dans une rubrique ou de l'affichage d'une variable dans le visualiseur de données.

Vous pouvez utiliser la fonction JSONParsedState pour découvrir si une valeur JSON donnée est associée à un JSON analysé stocké avec elle, si le JSON est valide et quel est son type.

Recommandations

Lors du traitement répété de grandes structures JSON (en particulier dans les boucles) ou de l'utilisation de plusieurs éléments dans les données JSON, l'ordre des opérations peut faire une différence conséquente en termes de performance.

Pour profiter de la mise en cache JSON automatique, il est préférable de ne pas alterner entre le chargement des données JSON à partir d'une rubrique, ou de ne pas passer à une autre rubrique puis de revenir à la première. Chaque fois qu'une fonction JSON traite un texte JSON différent, le JSON précédemment mis en cache est supprimé, de sorte que le texte doit être à nouveau analysé. Par exemple, cela donne la performance la plus lente :

Copier
# Exemple - Peu efficace
Définir variable [ $nom1 ; Valeur: JSONGetElement ( Table::JSON1 ; "nom" ) ]
Définir variable [ $nom2 ; Valeur: JSONGetElement ( Table::JSON2 ; "nom" ) ]
Définir variable [ $id1 ; Valeur: JSONGetElement ( Table::JSON1 ; "id" ) ]
Définir variable [ $id2 ; Valeur: JSONGetElement ( Table::JSON2 ; "id" ) ]

En réorganisant uniquement les actions de sorte à effectuer tout le travail sur les mêmes données JSON avant de travailler sur différentes données JSON, le cache automatique fonctionne en votre faveur, éliminant le besoin d'analyser les données de la même rubrique deux fois.

Copier
# Exemple - Meilleur
Définir variable [ $nom1 ; Valeur: JSONGetElement ( Table::JSON1 ; "nom" ) ]
Définir variable [ $id1 ; Valeur: JSONGetElement ( Table::JSON1 ; "id" ) ]
Définir variable [ $nom2 ; Valeur: JSONGetElement ( Table::JSON2 ; "nom" ) ]
Définir variable [ $id2 ; Valeur: JSONGetElement ( Table::JSON2 ; "id" ) ]

La méthode la plus efficace et la plus flexible consiste à utiliser la fonction JSONParse pour obtenir le texte JSON de chaque source, l'analyser et le stocker dans une variable. De cette façon, il n'est analysé qu'une seule fois. Ensuite, peu importe l'ordre dans lequel vous effectuez d'autres opérations (comme l'obtention ou la définition d'éléments) puisque ces fonctions JSON peuvent utiliser les variables, qui contiennent les représentations binaires déjà analysées.

Copier
# Exemple - Optimal
Définir variable [ $JSON1 ; Valeur: JSONParse ( Table::JSON1 ) ]
Définir variable [ $JSON2 ; Valeur: JSONParse ( Table::JSON2 ) ]

Définir variable [ $nom1 ; Valeur: JSONGetElement ( $JSON1 ; "nom" ) ]
Définir variable [ $nom2 ; Valeur: JSONGetElement ( $JSON2 ; "nom" ) ]
Définir variable [ $id1 ; Valeur: JSONGetElement ( $JSON1 ; "id" ) ]
Définir variable [ $id2 ; Valeur: JSONGetElement ( $JSON2 ; "id" ) ]

Gestion des erreurs dans les données JSON

Si une erreur se produit lors de l'analyse du paramètre json, les fonctions JSON renvoient le caractère « ? » suivi d'un message d'erreur de l'analyseur JSON.

Par exemple, lorsque le caractère « : » après la clé « boulangerie » manque dans l'Exemple de données JSON, ce calcul

Copier
JSONGetElement ( $$JSON ; "boulangerie.produit[0]id" )

renvoie ce message d'erreur :

Copier
? * Line 3, Column 2
  Missing ':' after object member name
* Line 13, Column 5
  Extra non-whitespace after JSON value.

Pour déterminer si les données JSON sont valides avant de les utiliser, utilisez la fonction JSONFormatElements et vérifiez si le premier caractère est « ? ». Par exemple :

Copier
Définir variable [ $Résultat ; Valeur: JSONFormatElements ( $$JSON ) ]
Si [ Début ( $Résultat ; 1 ) = "?" ]
   # $$JSON contient des données JSON non valides.
Fin de si

Sinon, pour déterminer si les données JSON sont valides et un type JSON spécifique avant de les utiliser, utilisez la fonction JSONGetElementType. Par exemple, pour tester si $$JSON est un objet JSON valide :

Copier
Définir variable [ $Résultat ; Valeur: JSONGetElementType ( $$JSON, "" ) ]
Si [ $Résultat ≠ JSONObject ]
    # $$JSON contient des données JSON non valides.
Fin de si

La fonction JSONParsedState offre une autre façon de détecter les erreurs. Elle indique si les données JSON ont été analysées et sont valides, et si oui, de quel type de données JSON il s'agit.

Copier
Définir variable [ $Résultat ; Valeur: JSONParse ( $$JSON ) ]
Définir variable [ $EtatAnalysé ; Valeur: JSONParsedState ( $Résultat ) ]
Si [ $EtatAnalysé < 0 ]
    # $$JSON a été analysé mais contient des données JSON invalides.
Sinon si [ $EtatAnalysé = 0 ]
    # $$JSON n'a pas été analysé.
Sinon si [ $EtatAnalysé > 0 ]
    # $$JSON a été analysé et est valide. $EtatAnalysé indique le type JSON.
    Définir variable [ $type ; Valeur: 
        Cas ( 
          $EtatAnalysé = JSONString ; "Type JSON est JSONString" ;
          $EtatAnalysé = JSONNumber ; "Type JSON est JSONNumber" ;
          $EtatAnalysé = JSONObject ; "Type JSON est JSONObject" ;
          $EtatAnalysé = JSONArray ; "Type JSON est JSONArray" ;
          $EtatAnalysé = JSONBoolean ; "Type JSON est JSONBoolean" ;
          $EtatAnalysé = JSONNull ; "Type JSON est JSONNull"
        )
    ]
    Ouvrir boîte dial. person. [ $type ]
Fin de si

Exemple de données JSON

L'exemple de données JSON suivant contient un objet « boulangerie » qui a un tableau de trois objets « produits », chacun avec plusieurs paires clé-valeur.

Copier
{
    "boulangerie"
    {
        "produit"
        [
            {
                "id" : "FB1",
                "nom" : "Donuts",
                "prix": 1.99,
                "stock" : 43,
                "catégorie" : "Pains",
                "offre spéciale" : true
            },
            {
                "id" : "FB2",
                "prix": 22.5,
                "nom" : "Gâteau au chocolat",
                "stock" : 23,
                "catégorie" : "Gâteaux"
                "offre spéciale" : true
            },
            {
                "id" : "FB3",
                "prix": 3.95,
                "nom" : "Baguette",
                "stock" : 34,
                "catégorie" : "Pains"
                "offre spéciale" : true
            }
        ]
    }
}

Remarques 

  • L'analyseur JSON conserve l'ordre des éléments dans un tableau, mais pas dans un objet. Par conséquent, il se peut que les fonctions JSON renvoient des éléments dans un objet dans un ordre différent de celui spécifié.

  • Dans les données JSON, les valeurs numériques fractionnelles doivent utiliser un point « . » comme séparateur décimal, quel que soit le séparateur spécifié par les formats système de votre ordinateur ou les formats utilisés lors de la création du fichier FileMaker Pro.