Guide de requêtes JSONPath : comment rechercher des données JSON
JSON est devenu la lingua franca du Web. Les API renvoient du JSON, les fichiers de configuration utilisent JSON, les bases de données stockent des documents JSON. Mais à mesure que les structures JSON deviennent plus grandes et plus profondément imbriquées, trouver des valeurs spécifiques devient de plus en plus difficile. C'est là qu'intervient JSONPath. JSONPath est un langage de requête qui vous permet de naviguer et d'extraire des données de documents JSON à l'aide d'expressions de chemin concises, tout comme XPath le fait pour XML. Ce guide couvre tout, de la syntaxe de base au filtrage avancé, avec des exemples pratiques que vous pouvez appliquer immédiatement.
Qu'est-ce que JSONPath ?
JSONPath est un langage de requête JSON, initialement proposé par Stefan Goessner en 2007. Il fournit une syntaxe compacte pour sélectionner des nœuds dans un document JSON, de manière analogue aux sélecteurs CSS pour les éléments HTML ou aux expressions XPath pour les nœuds XML. Au lieu d'écrire des boucles et une logique conditionnelle pour parcourir une structure JSON, vous écrivez une expression qui décrit le chemin vers les données souhaitées.
Les expressions JSONPath commencent à partir du nœud racine du document JSON et naviguent à travers les objets et tableaux jusqu'à la valeur souhaitée. Le langage prend en charge les jokers, la descente récursive, le slicing de tableaux et les expressions de filtrage, suffisamment puissants pour la plupart des besoins d'extraction de données.
Document JSON d'exemple
Dans ce guide, nous utiliserons le document JSON suivant comme exemple de travail. C'est l'exemple classique de la proposition JSONPath originale, avec des données supplémentaires ajoutées :
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J.R.R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}Référence de syntaxe JSONPath
JSONPath utilise un petit ensemble d'opérateurs qui se combinent pour former des requêtes puissantes. Voici la référence complète de la syntaxe :
| Opérateur | Description | Exemple |
|---|---|---|
| $ | Nœud racine du document | $ |
| . | Opérateur enfant (accès aux propriétés d'objet) | $.store |
| [] | Index de tableau ou opérateur enfant | $.store.book[0] |
| [*] | Joker pour tous les éléments du tableau | $.store.book[*] |
| .. | Descente récursive (recherche à tous les niveaux) | $..author |
| .key | Propriété d'objet nommée | $.store.bicycle |
| ['key'] | Notation entre crochets pour l'accès aux propriétés | $['store']['book'] |
| [start:end] | Slicing de tableau (index de fin exclus) | $.store.book[0:2] |
| [?()] | Expression de filtrage | < 10)] |
| () | Expression de script (selon l'implémentation) | $.store.book[(@.length-1)] |
Expressions JSONPath de base
Accès au nœud racine et aux enfants directs
Le signe dollar $ représente le nœud racine du document JSON. À partir de là, vous utilisez la notation par point pour accéder aux propriétés d'objet et la notation entre crochets pour accéder aux index de tableau.
| Expression | Résultat |
|---|---|
| $ | Document JSON entier |
| $.store | Objet store (contient le tableau book et l'objet bicycle) |
| $.store.bicycle | {"color": "red", "price": 19.95} |
| $.store.bicycle.color | "red" |
| $.store.book | Tableau book entier |
| $.store.book[0] | Premier objet livre |
| $.store.book[0].title | "Sayings of the Century" |
| $.store.book[3].author | "J.R.R. Tolkien" |
Notation entre crochets
La notation entre crochets est une alternative à la notation par point, utile lorsque les noms de propriétés contiennent des caractères spéciaux, des espaces ou commencent par un chiffre :
$.store['book'][0]['title']
$['store']['bicycle']['color']Les notations entre crochets et par point sont interchangeables pour les propriétés d'objet. Cependant, lorsque le nom de la propriété est dynamique ou contient des caractères invalides dans la notation par point, vous devez utiliser la notation entre crochets.
Opérateur joker
L'opérateur joker * correspond à tous les éléments d'un tableau ou à toutes les propriétés d'un objet. Il est extrêmement utile pour extraire toutes les valeurs d'un niveau sans connaître les clés ou index spécifiques.
| Expression | Résultat |
|---|---|
| $.store.* | Toutes les valeurs de l'objet store (tableau book et objet bicycle) |
| $.store.book[*] | Tous les livres du tableau (les quatre objets book) |
| $.store.book[*].author | Tous les noms d'auteurs : ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"] |
| $.store.*.price | Prix du bicycle et tableau book (pas le prix d'un livre individuel) |
Descente récursive : l'opérateur double point
L'opérateur double point .. est l'une des fonctionnalités les plus puissantes de JSONPath. Il recherche la clé spécifiée à chaque niveau de l'arbre JSON, pas seulement les enfants directs. Pensez-y comme une recherche en profondeur dans l'ensemble du document.
| Expression | Résultat |
|---|---|
| $..author | Toutes les valeurs author à toutes les positions du document |
| $..price | Toutes les valeurs price : [8.95, 12.99, 8.99, 22.99, 19.95] |
| $..book[2] | Troisième livre, recherche récursive |
| $..category | Toutes les valeurs category : ["reference", "fiction", "fiction", "fiction"] |
L'opérateur de descente récursive est particulièrement utile lorsque vous ne connaissez pas le chemin exact vers les données souhaitées, ou lorsque la même clé apparaît à plusieurs niveaux d'imbrication. Par exemple, si une réponse d'API contient des champs id à divers niveaux d'imbrication, $..id collectera tous les id.
Slicing de tableaux
Le slicing de tableaux vous permet de sélectionner une plage d'éléments dans un tableau. La syntaxe [start:end] sélectionne les éléments de l'index de début à l'index de fin (exclus). Les index positifs et négatifs sont pris en charge.
| Expression | Résultat |
|---|---|
| $.store.book[0:2] | Les deux premiers livres (index 0 et 1) |
| $.store.book[1:3] | Deuxième et troisième livres (index 1 et 2) |
| $.store.book[-1] | Dernier livre (The Lord of the Rings) |
| $.store.book[-2:] | Les deux derniers livres |
| $.store.book[:2] | Les deux premiers livres (identique à [0:2]) |
| $.store.book[2:] | Troisième livre et suivants |
Notez que le comportement du slicing peut varier légèrement selon les implémentations de JSONPath. La syntaxe ci-dessus suit la convention utilisée par la plupart des bibliothèques populaires et le standard IETF RFC 9535.
Expressions de filtrage
Les expressions de filtrage sont l'endroit où JSONPath devient vraiment puissant. Elles vous permettent de sélectionner des éléments en fonction de conditions plutôt que de leur position. La syntaxe de filtrage utilise [?(condition)], où la condition est évaluée pour chaque élément.
Opérateurs de comparaison
JSONPath prend en charge les opérateurs de comparaison suivants dans les expressions de filtrage :
| Opérateur | Signification | Exemple |
|---|---|---|
| == | Égal à | [?(@.category == "fiction")] |
| != | Différent de | [?(@.category != "fiction")] |
| < | Inférieur à | < 10)] |
| <= | Inférieur ou égal à | <= 8.99)] |
| > | Supérieur à | [?(@.price > 15)] |
| >= | Supérieur ou égal à | [?(@.price >= 12.99)] |
| =~ | Correspondance regex (certaines implémentations) | [?(@.author =~ /Tolkien/i)] |
Exemples de filtrage pratiques
En utilisant notre document d'exemple, voici des expressions de filtrage pratiques et leurs résultats :
Find all books cheaper than $10:
< 10)]Renvoie les livres « Sayings of the Century » (8,95 $) et « Moby Dick » (8,99 $).
Find all fiction books:
$.store.book[?(@.category == "fiction")]Renvoie trois livres : « Sword of Honour », « Moby Dick » et « The Lord of the Rings ».
Find books with an ISBN:
$.store.book[?(@.isbn)]Renvoie les livres ayant la propriété isbn : « Moby Dick » et « The Lord of the Rings ». C'est parce que le filtre vérifie si la propriété existe.
Find the most expensive book:
$.store.book[?(@.price > 20)]Renvoie « The Lord of the Rings » (22,99 $).
Opérateurs logiques dans les filtres
Vous pouvez combiner des conditions avec des opérateurs logiques :
< 10 && @.category == "fiction")]
$.store.book[?(@.price > 15 || @.category == "reference")]La première expression recherche les livres de fiction à moins de 10 $ (seulement « Moby Dick »). La seconde recherche les livres à plus de 15 $ ou appartenant à la catégorie référence (renvoie « Sayings of the Century » et « The Lord of the Rings »).
JSONPath vs XPath
JSONPath s'inspire explicitement de XPath, et les deux langages partagent de nombreuses similitudes conceptuelles. Si vous êtes familier avec le traitement XML, comprendre cette relation vous aidera.
| Fonctionnalité | JSONPath | XPath |
|---|---|---|
| Symbole racine | $ | / |
| Accès enfant | .key ou ['key'] | /element |
| Index de tableau | [0] | [1] (commence à 1) |
| Joker | * | * |
| Descente récursive | .. | // |
| Filtrage | [?(condition)] | [condition] |
| Attribut | Non applicable (JSON n'a pas d'attributs) | @attr |
| Nœud courant | @ (dans les filtres) | . ou current() |
| Parent | Non pris en charge | .. |
| Axes | Non pris en charge | 13 axes (ancestor, following, etc.) |
| Modèle de données | Objets et tableaux | Éléments, attributs, nœuds de texte |
La différence clé est que XPath opère sur un modèle d'arbre riche avec des éléments, des attributs, des nœuds de texte, des espaces de noms et des instructions de traitement. JSONPath opère sur un modèle plus simple d'objets (mappages clé-valeur) et de tableaux (listes ordonnées). Cette simplicité rend JSONPath plus facile à apprendre, mais moins expressif que XPath pour les requêtes complexes.
JSONPath en pratique
Tests d'API
JSONPath est indispensable pour les tests d'API. Lorsque vous envoyez une requête à une API et recevez une grande réponse JSON, JSONPath vous permet d'assertir des valeurs spécifiques sans naviguer manuellement dans toute la structure. La plupart des outils de test d'API prennent en charge nativement JSONPath.
Par exemple, dans un test, vous pourriez vérifier que le prix du premier livre est inférieur à 10 $ :
// Using a JSONPath assertion in testing
response.jsonPath().get("store.book[0].price").should(equals(8.95));
// Find all books by a specific author
response.jsonPath().get("store.book[?(@.author == 'Herman Melville')].title");
// Returns: ["Moby Dick"]Transformation de données
Lors de l'intégration de systèmes utilisant différents formats de données, JSONPath aide à extraire et transformer des champs spécifiques. Vous pouvez extraire des valeurs d'une structure JSON et les mapper vers une autre sans écrire de code de parcours complexe.
Gestion de configuration
Les fichiers de configuration complexes contiennent souvent du JSON profondément imbriqué. JSONPath vous permet d'interroger des valeurs de configuration spécifiques sans charger et analyser l'ensemble de la structure. Des outils comme jq utilisent une syntaxe similaire à JSONPath pour traiter le JSON dans des pipelines en ligne de commande.
Surveillance et alertes
Dans les systèmes d'observabilité, les requêtes JSONPath peuvent extraire des métriques de journaux et de réponses d'API au format JSON. Vous pouvez configurer des alertes qui se déclenchent lorsqu'une requête JSONPath renvoie une valeur dépassant un seuil.
Implémentations de JSONPath
JSONPath est disponible dans presque tous les langages de programmation. Voici les bibliothèques les plus populaires :
| Langage | Bibliothèque | Installation |
|---|---|---|
| JavaScript | jsonpath-plus | npm install jsonpath-plus |
| Python | jsonpath-ng | pip install jsonpath-ng |
| Java | JsonPath (Jayway) | Maven : com.jayway.jsonpath |
| C# | Json.NET (Newtonsoft) | NuGet : Newtonsoft.Json |
| Go | gjson | go get github.com/tidwall/gjson |
| PHP | jsonpath | composer require softcreatr/jsonpath |
| Ruby | jsonpath | gem install jsonpath |
Exemple JavaScript
< 10)]',
json: data
});
// Returns books with price < 10
Python Example
from jsonpath_ng import parse
data = { /* our sample JSON */ }
# Find all authors
author_expr = parse('$..author')
authors = [match.value for match in author_expr.find(data)]
# ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"]
# Find cheap books
cheap_expr = parse('$.store.book[?(@.price < 10)]')
cheap_books = [match.value for match in cheap_expr.find(data)]
Common Pitfalls and Tips
- Zero-based vs one-based indexing: JSONPath uses zero-based indexing (the first element is [0]), while XPath uses one-based indexing (the first element is [1]). This is a common source of off-by-one errors.
- Implementation differences: Before the IETF standard (RFC 9535), JSONPath implementations varied in their handling of edge cases like empty results, null values, and filter syntax. Always test your expressions with the specific library you are using.
- Filter performance: Recursive descent with filters (
$..book[?(@.price < 10)]) can be slow on large documents because it must traverse the entire tree. For performance-critical applications, use more specific paths when possible. - Case sensitivity: JSONPath is case-sensitive.
$.Storewill not match$.store. This is consistent with JSON's case-sensitive nature. - Indexation à base zéro vs à base un : JSONPath utilise l'indexation à base zéro (le premier élément est [0]), tandis que XPath utilise l'indexation à base un (le premier élément est [1]). C'est une source courante d'erreurs de décalage.
- Différences d'implémentation : avant le standard IETF (RFC 9535), les implémentations de JSONPath présentaient des différences dans le traitement des cas limites comme les résultats vides, les valeurs null et la syntaxe de filtrage. Testez toujours les expressions avec votre bibliothèque spécifique.
Pièges courants et astuces
En 2024, l'IETF a publié la RFC 9535, standardisant officiellement JSONPath. Cette spécification a résolu de nombreuses ambiguïtés et incohérences entre les implémentations. Les aspects clés du standard incluent :
- < 10)]) peut être lente sur des documents volumineux car elle doit parcourir l'arbre entier. Pour les applications critiques en performance, utilisez des chemins plus spécifiques dans la mesure du possible.
- Sensibilité à la casse : JSONPath est sensible à la casse. $.Store ne correspondra pas à $.store. Cela est cohérent avec la nature sensible à la casse de JSON.
- Échappement des caractères spéciaux : si un nom de clé contient un point ou des crochets, vous devez utiliser la notation entre crochets avec guillemets : $['key.with.dots'] au lieu de $.key.with.dots.
- Pas de traversée vers le parent : contrairement à XPath, JSONPath ne peut pas naviguer vers le nœud parent. Il n'y a pas d'équivalent de .. (axe parent) de XPath. Le .. de JSONPath signifie la descente récursive, pas le parent.
Si vous commencez un nouveau projet, privilégiez les bibliothèques implémentant la RFC 9535 pour une compatibilité maximale et un comportement prévisible.
Besoin d'interroger rapidement des données JSON ? Essayez notre testeur JSONPath en ligne gratuit pour évaluer des expressions en temps réel sur vos documents JSON.
Essayez le chercheur JSONPathStandard IETF : RFC 9535
Exemple Python
JSONPath est un langage de requête pour JSON, analogue à XPath pour XML. Il utilise des expressions de chemin pour naviguer et extraire des valeurs spécifiques dans des documents JSON. Une expression JSONPath comme $.store.book[0].title vous permet de cibler précisément des données dans des structures JSON imbriquées complexes sans écrire de code d'analyse personnalisé.
Qu'est-ce que JSONPath ?
JSONPath est conçu pour la structure d'objets et de tableaux de JSON, tandis que XPath est conçu pour l'arbre d'éléments et d'attributs de XML. JSONPath utilise $ comme nœud racine, la notation par point pour accéder aux objets et la notation entre crochets pour les tableaux. XPath utilise / pour la séparation de chemin et @ pour accéder aux attributs. JSONPath est plus simple mais moins riche en fonctionnalités que XPath.
En quoi JSONPath diffère-t-il de XPath ?
Le double point (..) dans JSONPath est l'opérateur de descente récursive. Il recherche la clé nommée à tous les niveaux de la structure JSON, pas seulement les enfants directs. Par exemple, $..author recherche toutes les clés author à n'importe quel endroit du document, quelle que soit leur profondeur d'imbrication.
Que signifie le double point (..) dans JSONPath ?
<, ><=, >< 10)] recherche tous les livres à moins de 10 $.
JSONPath peut-il filtrer des données en fonction de conditions ?
JSONPath a été initialement proposé par Stefan Goessner en 2007 sans spécification formelle, ce qui a conduit à des différences entre les implémentations. En 2024, l'IETF a publié la RFC 9535 pour standardiser officiellement JSONPath. Les implémentations modernes convergent vers ce standard, mais certaines bibliothèques plus anciennes peuvent encore présenter de légères différences de syntaxe.