4 Fonctionnalité JSONPath

Vue d'ensemble

Cette section présente les fonctionnalités JSONPath prises en charge dans les étapes de prétraitement des valeurs d'élément.

JSONPath est composé de segments séparés par des points. Un segment peut prendre la forme d'un mot simple, représentant un nom de valeur JSON, du caractère générique (*) ou d'une construction plus complexe placée entre crochets. Le point précédant un segment entre crochets est facultatif et peut être omis.

JSONPath example Description
$.object.name Renvoie le contenu de object.name.
$.object['name'] Renvoie le contenu de object.name.
$.object.['name'] Renvoie le contenu de object.name.
$["object"]['name'] Renvoie le contenu de object.name.
$.['object'].["name"] Renvoie le contenu de object.name.
$.object.history.length() Renvoie le nombre d'éléments du tableau object.history.
$[?(@.name == 'Object')].price.first() Renvoie la valeur de la propriété price du premier objet nommé "Object".
$[?(@.name == 'Object')].history.first().length() Renvoie le nombre d'éléments du tableau d'historique du premier objet nommé "Object".
$[?(@.price > 10)].length() Renvoie le nombre d'objets dont le prix est supérieur à 10.

Voir aussi : Échappement des caractères spéciaux des valeurs de macro LLD dans JSONPath.

Segments pris en charge

Segment Description
<name> Correspond à une propriété d’objet par son nom.
* Correspond à toutes les propriétés d’objet.
['<name>'] Correspond à une propriété d’objet par son nom.
['<name>', '<name>', ...] Correspond à une propriété d’objet par l’un des noms listés.
[<index>] Correspond à un élément de tableau par son index.
[<number>, <number>, ...] Correspond à un élément de tableau par l’un des index listés.
[*] Correspond à toutes les propriétés d’objet ou à tous les éléments de tableau.
[<start>:<end>] Correspond aux éléments de tableau selon la plage définie :
<start> - le premier index à faire correspondre (inclus) ; s’il n’est pas spécifié, tous les éléments du tableau depuis le début correspondent ; s’il est négatif, il indique un décalage de départ à partir de la fin du tableau ;
<end> - le dernier index à faire correspondre (exclu) ; s’il n’est pas spécifié, tous les éléments du tableau jusqu’à la fin correspondent ; s’il est négatif, il indique un décalage de départ à partir de la fin du tableau.
[?(<expression>)] Correspond aux objets/éléments de tableau en appliquant une expression de filtre.

Pour trouver un segment correspondant sans tenir compte de son ascendance (segment détaché), il doit être préfixé par deux points (..). Par exemple, $..name ou $..['name'] renvoient les valeurs de toutes les propriétés name.

Les noms des éléments correspondants peuvent être extraits en ajoutant un suffixe tilde (~) au JSONPath. Cela renvoie le nom de l’objet correspondant ou un index au format chaîne de l’élément de tableau correspondant. Le format de sortie suit les mêmes règles que les autres requêtes JSONPath : les résultats d’un chemin défini sont renvoyés « tels quels », et les résultats d’un chemin indéfini sont renvoyés dans un tableau. Cependant, il y a peu d’intérêt à extraire le nom d’un élément correspondant à un chemin défini, car il est déjà connu.

Expression de filtre

L'expression de filtre est une expression arithmétique en notation infixée.

Opérandes pris en charge :

Operand Description
"<text>"
'<text>'
Constante de texte.

Exemple :
'value: \\'1\\''
"value: '1'"
<number> Constante numérique prenant en charge la notation scientifique.

Exemple : 123
<jsonpath starting with $> Valeur référencée par le JSONPath depuis le nœud racine du document d'entrée ; seuls les chemins définis sont pris en charge.

Exemple : $.object.name
<jsonpath starting with @> Valeur référencée par le JSONPath depuis l'objet/élément actuel ; seuls les chemins définis sont pris en charge.

Exemple : @.name

Opérateurs pris en charge :

Operator Type Description Result
- Binary Soustraction Nombre
+ Binary Addition Nombre
/ Binary Division Nombre
* Binary Multiplication Nombre
== Binary Égalité Booléen (1/0)
!= Binary Inégalité Booléen (1/0)
< Binary Inférieur à Booléen (1/0)
<= Binary Inférieur ou égal à Booléen (1/0)
> Binary Supérieur à Booléen (1/0)
>= Binary Supérieur ou égal à Booléen (1/0)
=~ Binary Correspond à l'expression régulière Booléen (1/0)
! Unary NON booléen Booléen (1/0)
|| Binary OU booléen Booléen (1/0)
&& Binary ET booléen Booléen (1/0)

Fonctions

Les fonctions peuvent être utilisées à la fin d’un JSONPath. Plusieurs fonctions peuvent être chaînées si la fonction précédente renvoie une valeur acceptée par la fonction suivante.

Fonctions prises en charge :

Fonction Description Entrée Sortie
avg Valeur moyenne des nombres dans un tableau d’entrée Tableau de nombres Nombre
min Valeur minimale des nombres dans un tableau d’entrée Tableau de nombres Nombre
max Valeur maximale des nombres dans un tableau d’entrée Tableau de nombres Nombre
sum Somme des nombres dans un tableau d’entrée Tableau de nombres Nombre
length Nombre d’éléments dans un tableau d’entrée Tableau Nombre
first Le premier élément d’un tableau Tableau Une construction JSON (objet, tableau, valeur) selon le contenu du tableau d’entrée

Les fonctions d’agrégation JSONPath acceptent des valeurs numériques entre guillemets. Ces valeurs sont automatiquement converties de chaînes en types numériques lorsqu’une agrégation est nécessaire. Une entrée incompatible entraînera la génération d’une erreur par la fonction.

Valeur de sortie

Les JSONPath peuvent être divisés en chemins définis et indéfinis. Un chemin défini ne peut renvoyer que null ou une seule correspondance. Un chemin indéfini peut renvoyer plusieurs correspondances : JSONPath avec des listes de noms/index détachées ou multiples, des tranches de tableau ou des segments d’expression. Cependant, lorsqu’une fonction est utilisée, le JSONPath devient défini, car les fonctions produisent toujours une seule valeur.

Un chemin défini renvoie l’objet/le tableau/la valeur auquel il fait référence. En revanche, un chemin indéfini renvoie un tableau des objets/tableaux/valeurs correspondants.

L’ordre des propriétés dans les résultats de requête JSONPath peut ne pas correspondre à l’ordre d’origine des propriétés JSON en raison des méthodes d’optimisation internes. Par exemple, le JSONPath $.books[1]["author", "title"] peut renvoyer ["title", "author"]. S’il est essentiel de préserver l’ordre d’origine des propriétés, il convient d’envisager d’autres méthodes de post-traitement après la requête.

Règles de formatage des chemins

Les espaces (espace, caractère de tabulation) peuvent être utilisés dans les segments et expressions en notation entre crochets, par exemple : $[ 'a' ][ 0 ][ ?( $.b == 'c' ) ][ : -1 ].first( ).

Les chaînes doivent être entourées de guillemets simples (') ou doubles ("). À l’intérieur des chaînes, les guillemets simples ou doubles (selon ceux utilisés pour les entourer) ainsi que les barres obliques inverses (\) sont échappés avec le caractère barre oblique inverse (\).

Exemple

{
  "books": [
    {
      "category": "référence",
      "author": "Nigel Rees",
      "title": "Paroles du siècle",
      "price": 8.95,
      "id": 1
    },
    {
      "category": "fiction",
      "author": "Evelyn Waugh",
      "title": "Sword of Honour",
      "price": 12.99,
      "id": 2
    },
    {
      "category": "fiction",
      "author": "Herman Melville",
      "title": "Moby Dick",
      "isbn": "0-553-21311-3",
      "price": 8.99,
      "id": 3
    },
    {
      "category": "fiction",
      "author": "J. R. R. Tolkien",
      "title": "Le Seigneur des anneaux",
      "isbn": "0-395-19395-8",
      "price": 22.99,
      "id": 4
    }
  ],
  "services": {
    "delivery": {
      "servicegroup": 1000,
      "description": "Livraison le lendemain dans la ville locale",
      "active": true,
      "price": 5
    },
    "bookbinding": {
      "servicegroup": 1001,
      "description": "Impression et assemblage du livre au format A5",
      "active": true,
      "price": 154.99
    },
    "restoration": {
      "servicegroup": 1002,
      "description": "Diverses méthodes de restauration",
      "active": false,
      "methods": [
        {
          "description": "Nettoyage chimique",
          "price": 46
        },
        {
          "description": "Pressage des pages endommagées par l'humidité",
          "price": 24.5
        },
        {
          "description": "Réfection de la reliure d'un livre déchiré",
          "price": 99.49
        }
      ]
    }
  },
  "filters": {
    "price": 10,
    "category": "fiction",
    "no filters": "pas de \"filtres\""
  },
  "closed message": "Le magasin est fermé",
  "tags": [
    "a",
    "b",
    "c",
    "d",
    "e"
  ]
}
JSONPath Type Résultat
$.filters.price definite 10
$.filters.category definite fiction
$.filters['no filters'] definite pas de "filtres"
$.filters definite {
"price": 10,
"category": "fiction",
"no filters": "pas de \"filtres\""
}
$.books[1].title definite Sword of Honour
$.books[-1].author definite J. R. R. Tolkien
$.books.length() definite 4
$.tags[:] indefinite ["a", "b", "c", "d", "e" ]
$.tags[2:] indefinite ["c", "d", "e" ]
$.tags[:3] indefinite ["a", "b", "c"]
$.tags[1:4] indefinite ["b", "c", "d"]
$.tags[-2:] indefinite ["d", "e"]
$.tags[:-3] indefinite ["a", "b"]
$.tags[:-3].length() definite 2
$.books[0, 2].title indefinite ["Moby Dick", "Paroles du siècle"]
$.books[1]['author', "title"] indefinite ["Sword of Honour", "Evelyn Waugh"]
$..id indefinite [1, 2, 3, 4]
$.services..price indefinite [154.99, 5, 46, 24.5, 99.49]
$.books[?(@.id == 4 - 0.4 * 5)].title indefinite ["Sword of Honour"]

Remarque : cette requête montre que des opérations arithmétiques peuvent être utilisées dans les requêtes ; elle peut être simplifiée en $.books[?(@.id == 2)].title
$.books[?(@.id == 2 \|\| @.id == 4)].title indefinite ["Sword of Honour", "Le Seigneur des anneaux"]
$.books[?(!(@.id == 2))].title indefinite ["Paroles du siècle", "Moby Dick", "Le Seigneur des anneaux"]
$.books[?(@.id != 2)].title indefinite ["Paroles du siècle", "Moby Dick", "Le Seigneur des anneaux"]
$.books[?(@.title =~ " of ")].title indefinite ["Paroles du siècle", "Sword of Honour", "Le Seigneur des anneaux"]
$.books[?(@.price > 12.99)].title indefinite ["Le Seigneur des anneaux"]
$.books[?(@.author > "Herman Melville")].title indefinite ["Paroles du siècle", "Le Seigneur des anneaux"]
$.books[?(@.price > $.filters.price)].title indefinite ["Sword of Honour", "Le Seigneur des anneaux"]
$.books[?(@.category == $.filters.category)].title indefinite ["Sword of Honour","Moby Dick","Le Seigneur des anneaux"]
$.books[?(@.category == "fiction" && @.price < 10)].title indefinite ["Moby Dick"]
$..[?(@.id)] indefinite [
{
"price": 8.95,
"id": 1,
"category": "référence",
"author": "Nigel Rees",
"title": "Paroles du siècle"
},
{
"price": 12.99,
"id": 2,
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour"
},
{
"price": 8.99,
"id": 3,
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3"
},
{
"price": 22.99,
"id": 4,
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "Le Seigneur des anneaux",
"isbn": "0-395-19395-8"
}
]
$.services..[?(@.price > 50)].description indefinite ["Impression et assemblage du livre au format A5", "Réfection de la reliure d'un livre déchiré"]
$..id.length() definite 4
$.books[?(@.id == 2)].title.first() definite Sword of Honour
$..tags.first().length() definite 5

Remarque : $..tags est un chemin indéfini, il renvoie donc un tableau des éléments correspondants, c'est-à-dire [["a", "b", "c", "d", "e" ]] ; first() renvoie le premier élément, c'est-à-dire ["a", "b", "c", "d", "e"] ; length() calcule la longueur de l'élément, c'est-à-dire 5.
$.books[*].price.min() definite 8.95
$..price.max() definite 154.99
$.books[?(@.category == "fiction")].price.avg() definite 14.99
$.books[?(@.category == $.filters.xyz)].title indefinite Remarque : une requête sans correspondance renvoie NULL pour les chemins définis et indéfinis.
$.services[?(@.active=="true")].servicegroup indefinite [1001,1000]

Remarque : les constantes textuelles doivent être utilisées dans les comparaisons de valeurs booléennes.
$.services[?(@.active=="false")].servicegroup indefinite [1002]

Remarque : les constantes textuelles doivent être utilisées dans les comparaisons de valeurs booléennes.
$.services[?(@.servicegroup=="1002")]~.first() definite restoration