La première fois que j'ai écrit une expression JSONPath qui comptait, je me suis trompé trois fois avant qu'elle ne fonctionne, et je savais seulement que c'était mal parce que la passerelle API que je configurais a renvoyé une stratégie vide au lieu du champ que je voulais Il n'y avait pas de boucle de rétroaction Je modifierais l'expression, je me redéployerais et j'attendrais Une fois que j'ai commencé à garder un testeur JSONPath ouvert dans un autre onglet, ce même travail a pris deux minutes au lieu d'un après-midi Ce guide traite de la façon dont j'utilise le Testeur JSONPath sur Toolz.dev, ce que fait réellement la syntaxe, et les petits pièges qui font qu'une expression ne renvoie rien quand on était sûr qu'elle devrait correspondre.
tl;dr : JSONPath est un langage de requête pour JSON, comme XPath l'est pour XML Un testeur JSONPath évalue une expression comme
$.store.book[*].authorcontre un document et retourne chaque valeur correspondante plus son chemin. Le Testeur JSONPath le fait entièrement dans votre navigateur, avec la prise en charge des caractères génériques, de la descente récursive, des tranches, des unions et des expressions de filtrage, afin que vous puissiez créer et déboguer une requête contre des données réelles avant de la coller dans le code.
Qu'est-ce que JSONPath ?
JSONPath est une syntaxe compacte pour sélectionner des parties d'un document JSON Vous écrivez un court chemin qui décrit un itinéraire à travers les données, et l'évaluer renvoie la valeur ou les valeurs à cet itinéraire L'idée vient de Stefan Goessner' ; proposition de 2007« , qui reflétait délibérément XPath afin que quiconque avait interrogé XML se sente chez lui. Pendant des années, il n’y avait aucune spécification formelle, juste cet article et une famille d’implémentations qui étaient pour la plupart d’accord, et début 2024, l’IETF a publié RFC9535 épingler la grammaire.
Vous rencontrez JSONPath plus souvent que vous ne pourriez vous y attendre C'est le langage sélecteur dans les outils de test API comme Postman et Karate, dans Kubernetes kubectl formatage de sortie, dans AWS CloudWatch et Step Functions, dans les processeurs de journaux et dans des dizaines de plates-formes low-code où un utilisateur doit extraire un champ d'une charge utile de webhook sans écrire de code. L'apprendre une fois rapporte sur tous ceux-ci.
Le modèle mental est simple Un document JSON est un arbre Les objets ont nommé des branches, les tableaux ont des branches numérotées, et les feuilles sont vos valeurs scalaires Une expression JSONPath est un ensemble de directions pour marcher sur cet arbre, et le résultat est chaque feuille ou sous-arbre sur lequel vous atterrissez Là où il devient puissant est qu'une seule expression peut atterrir à plusieurs endroits à la fois.
Que fait réellement un testeur JSONPath ?
Un testeur prend deux entrées, votre JSON et une expression, et vous montre chaque nœud sélectionné par l'expression Cela semble évident, mais la valeur est dans le feedback Lorsqu'une expression ne renvoie rien, ou renvoie plus que ce à quoi vous vous attendiez, un testeur transforme un jeu de devinettes en une vérification de deux secondes, car vous pouvez voir exactement quels nœuds correspondaient et ajuster un caractère à la fois.
Sur Toolz.dev le flux est court Coller un document JSON, ou charger l'exemple de librairie que la plupart des tutoriels JSONPath utilisent, taper une expression et évaluer L'outil répertorie chaque valeur appariée avec un décompte en cours d'exécution, et vous pouvez basculer la sortie entre trois vues Les valeurs vous donnent juste les résultats comme un tableau JSON Les chemins vous donnent l'emplacement normalisé de chaque correspondance, ce qui est le moyen le plus rapide de découvrir l'expression dont vous avez réellement besoin Les entrées vous donnent les deux ensemble, afin que vous puissiez voir le chemin et la valeur côte à côte.
La raison de tester par rapport à des données réelles plutôt que de raisonner à ce sujet dans votre tête est que JSON from the wild est plus désordonné que les exemples Un champ est parfois un objet et parfois un tableau Une clé à laquelle vous vous attendiez manque sur la moitié des enregistrements Un nombre est arrivé sous forme de chaîne Exécuter l'expression contre la charge utile réelle fait surface ces surprises immédiatement au lieu de l'heure de déploiement.
Comment puis-je sélectionner des éléments dans un tableau ?
Les tableaux sont l'endroit où se déroulent la plupart des travaux de JSONPath, et il existe quatre façons de les aborder.
Un seul index sélectionne un élément. $.store.book[0] retourne le premier livre, et JSONPath, comme la plupart des langues, compte à partir de zéro Un indice négatif compte à partir de la fin, donc $.store.book[-1] retourne le dernier livre sans que vous ayez besoin de savoir combien il y en a. Ce formulaire négatif est véritablement utile lorsque vous souhaitez l'élément le plus récent dans un journal ou la dernière entrée d'un flux.
Une wildcard sélectionne chaque élément. $.store.book[*] retourne les quatre livres, et $.store.book[*].author retourne l'auteur de chacun, vous donnant un éventail propre d'auteurs Le caractère générique fonctionne également sur les objets, où $.store.* renvoie chaque valeur de l'objet de stockage, quelle que soit la clé.
Une union sélectionne un ensemble spécifique. $.store.book[0,2] renvoie les premier et troisième livres, et la même syntaxe de virgule fonctionne avec les noms, donc $['store']['bicycle'] et les touches entre crochets vous permettent d'adresser des touches contenant des espaces ou une ponctuation que la forme de point ne peut pas contenir.
Une tranche sélectionne une plage, empruntant Python' ;s start:end:step formulaire. $.store.book[:2] prend les deux premiers, $.store.book[1:3] prend une plage médiane avec l'index final exclusif, $.store.book[::2] prend chaque deuxième élément, et $.store.book[::-1] inverse le tableau Les tranches sont la partie la moins connue de la syntaxe et celle qui enregistre le plus de frappe une fois que vous l'avez.
Que fait le double point ?
Le double point est une descente récursive, et c'est la fonctionnalité qui donne à JSONPath l'impression d'être une recherche plutôt qu'un chemin. $..author trouve chaque author clé n'importe où dans le document, peu importe la profondeur à laquelle il est imbriqué, et $..* retourne chaque valeur à chaque niveau Lorsque vous ne connaissez pas la forme exacte d'un document, ou lorsque le même champ apparaît à plusieurs profondeurs, la descente récursive les trouve toutes dans une seule expression.
Considérez l'exemple de librairie. $..price renvoie cinq valeurs, les quatre prix du livre et le prix du vélo, car il descend dans chaque objet et collecte chaque price ça trouve. Une plaine $.store.book[*].price ne renverrait que les quatre prix du livre, car il parcourt un itinéraire fixe La différence entre ces deux expressions est la différence entre demander des prix dans un endroit connu et demander des prix n'importe où.
La descente récursive est suffisamment puissante pour être dangereuse, dans le sens où elle peut correspondre à plus que ce que vous vouliez dire C'est exactement pourquoi un testeur compte ici Courez $..name contre une charge utile inconnue et vous pourriez découvrir qu'elle correspond à un nom d'utilisateur, un nom de produit et un nom de fichier que vous n'aviez aucune idée de partager une clé. Voir les chemins dans la sortie vous indique s'il faut restreindre l'expression avant de vous y fier.
Comment fonctionnent les expressions de filtre ?
Un filtre ne conserve que les éléments pour lesquels une condition est vraie, et il est écrit [?(...)] avec @ représentant l'élément actuel. $.store.book[?(@.price < 10)] retourne les livres moins cher que dix À l'intérieur du filtre, vous pouvez comparer un champ par rapport à un littéral avec les opérateurs ==, !=, <, <=, >, et >=: testez la simple présence d'un champ et combinez les conditions avec && et ||.
Quelques exemples concrets en montrent clairement la forme
$.store.book[?(@.category == "fiction")]sélectionne les titres de fiction.$.store.book[?(@.price < 10 && @.category == "fiction")]se rétrécit à la fiction bon marché.$.store.book[?(@.isbn)]sélectionne uniquement les livres qui ont un ISBN, en utilisant l'existence plutôt que la comparaison.$.vals[?(@ > 2)]filtre un tableau simple de nombres, où@à lui seul, il fait référence à l’élément lui-même.
Le bug de filtre le plus courant est une inadéquation de type. Dans JSON, "12" et 12 sont des valeurs différentes, donc un filtre qui compare un champ numérique à un nombre cité, ou un champ de chaîne à un nombre nu, ne correspond silencieusement à rien Quand un filtre vous surprend, la première chose à vérifier est si le champ et le littéral sont du même type Tester l'expression par rapport aux données réelles, où vous pouvez voir les valeurs réelles, est comment vous attrapez cela en secondes au lieu d'après un déploiement raté.
JSONPath contre JSON Pointer contre une différence JSON
Ces trois outils touchent tous la structure JSON, mais ils répondent à des questions différentes, et choisir le mauvais perd du temps Voici comment ils se comparent :
| s'approche | Réponses | allumette | le mieux pour |
|---|---|---|---|
| JSONPath | Quels nœuds satisfont à cette requête ? | Zéro, un ou plusieurs | Extraction de champs, filtrage de tableaux, exploration de formes inconnues |
| Pointeur JSON (RFC 6901) | Qu'est-ce qu'il y a à cet endroit exact ? | Toujours exactement un | Référencement d'un seul champ fixe, comme dans JSON Schema $ref |
| JSON diff | Qu'est-ce qui a changé entre deux documents ? | Un ensemble de changements | Comparaison de deux versions des mêmes données |
JSON Pointer, défini dans RFC6901« , s'adresse à un endroit précis avec un chemin séparé par des barres obliques comme » /store/book/0/title(en), et il n'utilise jamais de caractères génériques ou de filtres Atteignez-le lorsque vous devez nommer un seul champ sans ambiguïté Atteignez JSONPath lorsqu'une seule expression doit sélectionner un ensemble de champs Et lorsque votre vraie question est ce qui diffère entre deux charges utiles plutôt que ce qu'une requête sélectionne, un Diff JSON est le bon outil Savoir lequel des trois vous avez réellement besoin est la moitié de la bataille.
Pourquoi mon expression ne renvoie-t-elle aucun résultat ?
Un résultat vide vient presque toujours d’une des rares causes, et un testeur vous permet de les exclure rapidement.
Le premier est un décalage structurel, Vous avez écrit $.data.items.name alors que items est un tableau, vous aviez donc besoin $.data.items[*].name avec un caractère générique La forme de point entre dans un objet, et un tableau n'est pas un objet avec un name clé, donc les impasses du chemin. Le fait de basculer la vue de sortie sur les chemins et de faire passer l'expression un segment à la fois vous montre exactement où elle cesse de correspondre.
La seconde est une faute d'orthographe ou de casing Les touches JSON sont sensibles à la casse, donc $.userId ne correspondra pas à a userID field, et un espace de fin ou une faute de frappe dans un nom de clé produit le même rien silencieux Parce que le testeur vous montre le document juste à côté de l'expression, ceux-ci sont rapides à repérer.
Le troisième, comme couvert ci-dessus, est une inadéquation de type de filtre, où une comparaison numérique s'exécute contre une valeur de chaîne ou l'inverse La quatrième est en supposant une clé existe sur chaque élément quand il existe sur seulement certains Les filtres récursifs de descente et d'existence sont les remèdes habituels Dans tous les cas, le correctif vient de regarder quels nœuds l'expression touche, ce qui est précisément ce qu'un testeur est pour.
Si vous construisez sur la pile comme moi, en passant d'une API Laravel à une interface frontale React et à un script shell occasionnel, JSONPath apparaît dans les trois, et un testeur basé sur un navigateur qui ne télécharge jamais vos données est l'outil que je garde le plus proche J'ai écrit sur la façon dont des utilitaires comme celui-ci s'intègrent dans un kit plus large dans le Boîte à outils pour les développeurs Web« Et les arguments en faveur du maintien de ce type de travail du côté client sont en faveur du client » Confidentialité des données dans les outils en ligne guide.
Comment cela s'accorde-t-il avec le reste de mon workflow JSON ?
Un testeur JSONPath est rarement le seul outil ouvert Lorsque le JSON que j'interroge est arrivé minifié ou avec une indentation incohérente, je le fais passer par le Formateur JSON tout d'abord pour que je puisse lire la structure pendant que j'écris l'expression Le formateur et le testeur ensemble sont la façon dont je passe d'une réponse API illisible à une requête de travail.
Une fois que je sais quels champs je tiens à moi, l'étape suivante consiste souvent à les remodeler Si je dois introduire les valeurs sélectionnées dans une feuille de calcul ou un fichier d'environnement, le Aplatit JSON transforme la structure imbriquée en clés à notation de points, et sa syntaxe de chemin est suffisamment proche de JSONPath pour que les deux se renforcent mutuellement Si je construis un type pour les données dans TypeScript, le JSON vers le script converter génère l'interface, et si je dois valider la forme plutôt que de simplement la lire, le Générateur de schéma JSON produit un schéma auquel je peux ajouter des contraintes JSONPath est l'étape d'exploration ; ces outils sont ce que je fais avec ce que je trouve.
Le point de confidentialité mérite d'être répété car le travail de JSONPath se produit si souvent contre des données sensibles Les réponses API transportent des jetons, des enregistrements utilisateur et des identifiants internes, et les coller dans un outil côté serveur signifie faire confiance à quelqu'un d'autre et aux journaux n°39 ; parce que le testeur Toolz.dev analyse et évalue entièrement dans votre navigateur, rien de tout cela ne laisse votre machine, et l'outil continue de travailler avec le réseau déconnecté C'est la différence entre un outil que vous pouvez utiliser sur une charge utile de mise en scène et un outil que vous pouvez utiliser sur la vraie chose.
Questions fréquentes
Dans quel cas JSONPath est-il utilisé ?
JSONPath est utilisé pour sélectionner et extraire des parties d'un document JSON avec une seule expression C'est le langage de requête dans les outils de test API, le formatage de sortie Kubernetes, les services cloud comme AWS Step Functions, et de nombreuses plates-formes low-code, partout où quelqu'un a besoin de tirer un champ ou de filtrer un tableau d'une charge utile JSON sans écrire de code procédural.
Comment sélectionner chaque élément d'un tableau dans JSONPath ?
Utilisez le caractère générique, donc $.items[*] renvoie chaque élément du tableau d'éléments et $.items[*].id retourne l'id de chacun Vous pouvez également sélectionner un élément par index avec $.items[0], le dernier élément avec l'indice négatif $.items[-1][TRADUCTION], un ensemble avec une union comme $.items[0,2]ou une plage avec une tranche comme $.items[1:3].
Que signifie le double point dans JSONPath ?
Le double point est une descente récursive, qui recherche à n'importe quelle profondeur. $..author trouve chaque clé d'auteur n'importe où dans le document, quelle que soit sa profondeur, et $..* renvoie chaque valeur à chaque niveau C'est le moyen le plus rapide de tirer un champ d'un document dont vous ne connaissez pas la structure exacte à l'avance.
Comment fonctionnent les expressions de filtre dans JSONPath ?
Un filtre [?(...)] ne conserve que les éléments pour lesquels une condition est vraie, avec @ en se référant à l'élément courant Par exemple $.book[?(@.price < 10)] retourne les livres moins chers que dix, et vous pouvez combiner les conditions avec && et ||: tels que [?(@.price < 10 && @.category == "fiction")]. Vous pouvez également tester un champ' ;s existence avec [?(@.isbn)].
Pourquoi mon expression JSONPath ne renvoie rien ?
Les deux causes les plus courantes sont une inadéquation structurelle et une inadéquation de type Vérifiez que chaque clé existe et est orthographiée avec le casse exact, et que vous avez utilisé une wildcard où les données sont un tableau plutôt qu'un objet Dans les filtres, rappelez-vous que " ;12" ; et 12 sont des valeurs différentes, alors comparez un champ de chaîne à une valeur citée et un champ numérique à un nombre nu.
Quelle est la différence entre JSONPath et JSON Pointer ?
Un JSON Pointer adresse un emplacement exact, comme /store/book/0/title, et renvoie toujours une seule valeur JSONPath est un langage de requête où une seule expression peut faire correspondre plusieurs nœuds à la fois via des caractères génériques, une descente récursive et des filtres Utilisez un pointeur pour référencer un champ fixe, et JSONPath pour sélectionner un ensemble de champs ou filtrer une collection.
Puis-je voir le chemin de chaque match, pas seulement la valeur ?
Oui. Basculez le mode de sortie sur les chemins pour obtenir l'emplacement normalisé de chaque correspondance, ou les entrées pour obtenir le chemin et la valeur ensemble Voir les chemins réels est le moyen le plus rapide d'affiner une expression jusqu'à ce qu'elle sélectionne exactement les nœuds que vous avez prévu, ce qui est particulièrement utile avec la descente récursive.
Mon JSON est-il téléchargé lorsque j'utilise le testeur ?
Non. Le document est analysé et l'expression est évaluée dans votre navigateur avec JavaScript, donc rien n'est transmis, enregistré ou stocké. Vous pouvez le confirmer en regardant l'onglet réseau pendant que vous exécutez une requête, ou en vous déconnectant d'Internet, car le testeur continue de fonctionner hors ligne une fois la page chargée.
Essayez-le sur vos propres données gratuitement Testeur JSONPath. Il évalue les caractères génériques, la descente récursive, les tranches, les unions et les expressions de filtrage entièrement dans votre navigateur, sans rien télécharger.



