Aller au contenu principal

1. Introduction (Introduction)

1. Introduction

JSON [RFC8259] est un format de représentation courant pour les données structurées. JSONPath définit une syntaxe de chaîne pour sélectionner et extraire des valeurs JSON à l'intérieur d'une valeur JSON donnée.

Par rapport à JSON Pointer [RFC6901], JSONPath n'est pas destiné à le remplacer mais à en être un compagnon plus puissant. Voir l'appendice C.

1.1. Terminology (Terminologie)

Les mots clés « MUST », « MUST NOT », « REQUIRED », « SHALL », « SHALL NOT », « SHOULD », « SHOULD NOT », « RECOMMENDED », « NOT RECOMMENDED », « MAY » et « OPTIONAL » dans ce document doivent être interprétés comme décrit dans le BCP 14 [RFC2119] [RFC8174] lorsqu'ils apparaissent en majuscules comme indiqué ici.

Les règles grammaticales de ce document doivent être interprétées comme de l'ABNF, comme décrit dans [RFC5234]. Les valeurs terminales ABNF dans ce document définissent des valeurs scalaires Unicode plutôt que leur encodage UTF-8. Par exemple, le signe PLACE OF INTEREST (U+2318) serait défini en ABNF comme %x2318.

Les fonctions sont désignées par le nom de la fonction suivi d'une paire de parenthèses, comme dans fname().

La terminologie de [RFC8259] s'applique sauf précisions ci-dessous. Les termes « primitive » et « structurée » servent à regrouper différents types de valeurs comme à la section 1 de [RFC8259]. Les objets et tableaux JSON sont structurés ; toutes les autres valeurs sont primitives. Les définitions de « object », « array », « number » et « string » restent inchangées. En particulier, « object » et « array » ne prennent pas un sens générique comme dans un contexte de programmation général.

La terminologie de [RFC9485] s'applique.

Les termes supplémentaires utilisés dans ce document sont définis ci-dessous.

Value (Valeur) : Conformément à [RFC8259], un élément de données conforme au modèle de données générique de JSON, c'est-à-dire des données primitives (nombres, chaînes de texte et les valeurs spéciales null, true et false), ou des données structurées (objets et tableaux JSON). [RFC8259] se concentre sur la représentation textuelle des valeurs JSON et ne définit pas entièrement l'abstraction de valeur supposée ici.

Member (Membre) : Une paire nom/valeur dans un objet. (Un membre n'est pas lui-même une valeur.)

Name (Nom) : Le nom (une chaîne) dans une paire nom/valeur constituant un membre. Ceci est aussi utilisé dans [RFC8259], mais cette spécification ne le définit pas formellement. Il est inclus ici pour exhaustivité.

Element (Élément) : Une valeur dans un tableau JSON.

Index (Indice) : Un entier qui identifie un élément précis dans un tableau.

Query (Requête) : Nom court pour une expression JSONPath.

Query Argument (Argument de requête) : Nom court pour la valeur à laquelle une expression JSONPath est appliquée.

Location (Emplacement) : La position d'une valeur dans l'argument de requête. On peut y penser comme à une séquence de noms et d'indices menant à la valeur à travers les objets et tableaux de l'argument de requête, la séquence vide indiquant l'argument de requête lui-même. Un emplacement peut être représenté comme un chemin normalisé (Normalized Path, défini ci-dessous).

Node (Nœud) : La paire formée d'une valeur et de son emplacement dans l'argument de requête.

Root Node (Nœud racine) : Le nœud unique dont la valeur est l'intégralité de l'argument de requête.

Root Node Identifier (Identifiant de nœud racine) : L'expression $, qui désigne le nœud racine de l'argument de requête.

Current Node Identifier (Identifiant de nœud courant) : L'expression @, qui désigne le nœud courant dans le contexte de l'évaluation d'une expression de filtre (décrite plus loin).

Children (Enfants) (d'un nœud) : Si le nœud est un tableau, les nœuds de ses éléments ; si le nœud est un objet, les nœuds de ses valeurs de membre. Si le nœud n'est ni un tableau ni un objet, il n'a pas d'enfants.

Descendants (Descendants) (d'un nœud) : Les enfants du nœud, ainsi que les enfants de ses enfants, et ainsi de suite récursivement. Plus formellement, la relation « descendants » entre nœuds est la clôture transitive de la relation « enfants ».

Depth (Profondeur) (d'un nœud descendant dans une valeur) : Le nombre d'ancêtres du nœud dans la valeur. Le nœud racine de la valeur a la profondeur zéro, les enfants du nœud racine ont la profondeur un, leurs enfants ont la profondeur deux, et ainsi de suite.

Nodelist (Liste de nœuds) : Une liste de nœuds. Bien qu'une nodelist puisse être représentée en JSON, par ex. comme un tableau, ce document n'exige ni ne suppose une représentation particulière.

Parameter (Paramètre) : Paramètre formel (d'une fonction) pouvant recevoir un argument de fonction (paramètre effectif) dans une expression de fonction.

Normalized Path (Chemin normalisé) : Une forme d'expression JSONPath qui identifie un nœud dans une valeur en fournissant une requête qui aboutit exactement à ce nœud. Chaque nœud dans un argument de requête est identifié par exactement un chemin normalisé (on dit que le chemin normalisé est « unique » pour ce nœud), et pour être un chemin normalisé pour un argument de requête donné, le chemin normalisé doit identifier exactement un nœud. Ceci est similaire, mais syntaxiquement différent, d'un JSON Pointer [RFC6901]. Note : Cette définition repose sur la définition syntaxique de la section 2.7 ; les expressions JSONPath qui identifient un nœud dans une valeur mais ne se conforment pas à cette syntaxe ne sont pas des chemins normalisés.

Unicode Scalar Value (Valeur scalaire Unicode) : Tout point de code Unicode [UNICODE] sauf les points de substitution haut et bas (en d'autres termes, des entiers dans les plages hexadécimales inclusives soit 0 à D7FF soit E000 à 10FFFF). Les requêtes JSONPath sont des séquences de valeurs scalaires Unicode.

Segment (Segment) : L'un des construits qui sélectionne des enfants ([<selectors>]) ou des descendants (..[<selectors>]) d'une valeur d'entrée.

Selector (Sélecteur) : Un élément unique dans un segment qui prend la valeur d'entrée et produit une nodelist constituée de nœuds enfants de la valeur d'entrée.

Singular Query (Requête singulière) : Une expression JSONPath construite à partir de segments syntaxiquement restreints d'une certaine manière (section 2.3.5.1) de sorte que, quelle que soit la valeur d'entrée, l'expression produit une nodelist contenant au plus un nœud. Note : Les expressions JSONPath qui produisent toujours une nodelist singulière mais ne se conforment pas à la syntaxe de la section 2.3.5.1 ne sont pas des requêtes singulières.

1.1.1. JSON Values as Trees of Nodes (Valeurs JSON comme arbres de nœuds)

Ce document modélise l'argument de requête comme un arbre de valeurs JSON, chacune avec son propre nœud. Un nœud est soit le nœud racine soit l'un de ses descendants.

Ce document modélise le résultat de l'application d'une requête à l'argument de requête comme une nodelist (une liste de nœuds).

Les nœuds sont les parties sélectionnables de l'argument de requête. Les seules parties d'un objet qu'une requête peut sélectionner sont les valeurs de membre. Les noms de membre et les membres (paires nom/valeur) ne peuvent pas être sélectionnés. Ainsi, les valeurs de membre ont des nœuds, mais pas les membres ni les noms de membres. De même, les valeurs de membre sont des enfants d'un objet, mais pas les membres ni les noms de membres.

1.2. History (Historique)

Ce document repose sur la proposition JSONPath populaire de Stefan Gössner (datée du 2007-02-21) [JSONPath-orig], s'appuie sur l'expérience du déploiement généralisé de ses implémentations et fournit une spécification normative pour celle-ci.

L'appendice B décrit comment JSONPath a été inspiré par XPath [XPath] pour XML.

JSONPath était destiné à être un compagnon léger aux implémentations JSON dans des langages comme PHP et JavaScript ; au lieu de définir son propre langage d'expressions comme XPath, JSONPath déléguait des parties d'une requête à l'environnement d'exécution sous-jacent, par ex. la fonction eval() de JavaScript. À mesure que JSONPath était implémenté dans davantage d'environnements, les expressions JSONPath devenaient de moins en moins portables. Par exemple, le traitement des expressions régulières était souvent délégué à un moteur d'expressions régulières pratique.

Ce document vise à supprimer de telles dépendances spécifiques à l'implémentation et à servir de spécification JSONPath commune utilisable dans tous les langages et environnements. Cela signifie que la rétrocompatibilité n'est pas toujours atteinte ; un principe de conception de ce document est de privilégier un « consensus » entre implémentations même s'il est approximatif, tant que cela ne met pas en péril l'objectif d'obtenir un langage de requête JSON utilisable et stable.

Le terme JSONPath a été choisi en raison de l'inspiration XPath et aussi parce que le résultat d'une requête consiste en des chemins identifiant des nœuds dans l'argument de requête JSON.

1.3. JSON Values (Valeurs JSON)

La valeur JSON à laquelle une requête JSONPath est appliquée est, par définition, une valeur JSON valide. Une valeur JSON est souvent construite en analysant un texte JSON.

L'analyse d'un texte JSON en une valeur JSON et ce qui se produit si un texte JSON ne représente pas du JSON valide ne sont pas définis par ce document. Les sections 4 et 8 de [RFC8259] identifient des situations spécifiques qui peuvent être conformes à la grammaire des textes JSON mais ne sont pas des usages interopérables de JSON, car elles peuvent provoquer un comportement imprévisible. Ce document ne tente pas de définir un comportement prévisible pour les requêtes JSONPath dans ces situations.

Plus précisément, les sous-sections « Semantics » des sections 2.3.1, 2.3.2, 2.3.5 et 2.5.2 décrivent un comportement qui devient imprévisible lorsque la valeur JSON pour l'un des objets considérés a été construite à partir d'un texte JSON présentant plusieurs membres pour un seul objet partageant le même nom de membre (« duplicate names », noms dupliqués ; voir la section 4 de [RFC8259]). De plus, lors de la sélection d'un enfant par nom (section 2.3.1) et de la comparaison de chaînes (section 2.3.5.2.2), on suppose que ces chaînes sont des séquences de valeurs scalaires Unicode ; le comportement devient imprévisible si ce n'est pas le cas (section 8.2 de [RFC8259]).

1.4. Overview of JSONPath Expressions (Aperçu des expressions JSONPath)

Une expression JSONPath est appliquée à une valeur JSON, appelée argument de requête. La sortie est une nodelist.

Une expression JSONPath consiste en un identifiant suivi d'une série de zéro ou plusieurs segments, chacun contenant un ou plusieurs sélecteurs.

1.4.1. Identifiers (Identifiants)

L'identifiant de nœud racine $ désigne le nœud racine de l'argument de requête, c'est-à-dire l'argument dans son ensemble.

L'identifiant de nœud courant @ désigne le nœud courant dans le contexte de l'évaluation d'une expression de filtre (section 2.3.5).

1.4.2. Segments (Segments)

Les segments sélectionnent des enfants ([<selectors>]) ou des descendants (..[<selectors>]) d'une valeur d'entrée.

Les segments peuvent utiliser la notation entre crochets (bracket notation), par exemple :

$['store']['book'][0]['title']

ou la notation point (dot notation) plus compacte, par exemple :

$.store.book[0].title

La notation entre crochets contient un ou plusieurs sélecteurs (séparés par des virgules) de tout type. Les sélecteurs sont détaillés à la section suivante.

Une expression JSONPath peut combiner notation entre crochets et notation point.

Ce document traite la notation entre crochets comme canonique et définit la notation point abrégée en fonction de la notation entre crochets. Les exemples et descriptions utilisent l'abréviation lorsque c'est pratique.

1.4.3. Selectors (Sélecteurs)

Un sélecteur de nom, par ex. 'name', sélectionne un enfant nommé d'un objet.

Un sélecteur d'indice, par ex. 3, sélectionne un enfant indexé d'un tableau.

Dans l'expression [], un joker * (section 2.3.2) sélectionne tous les enfants d'un nœud, et dans l'expression ..[], il sélectionne tous les descendants d'un nœud.

Une tranche de tableau start:end:step (section 2.3.4) sélectionne une série d'éléments d'un tableau, avec une position de départ, une position de fin et une valeur de pas optionnelle qui fait avancer la position du début à la fin.

Une expression de filtre ?<logical-expr> sélectionne certains enfants d'un objet ou d'un tableau, comme dans :

$.store.book[[email protected] < 10].title

1.4.4. Summary (Synthèse)

Le tableau 1 donne un bref aperçu de la syntaxe JSONPath.

Élément de syntaxeDescription
$identifiant de nœud racine (section 2.2)
@identifiant de nœud courant (section 2.3.5)
(valable uniquement dans les sélecteurs de filtre)
[<selectors>]segment enfant (section 2.5.1) : sélectionne
zéro ou plusieurs enfants d'un nœud
.nameabréviation pour ['name']
.*abréviation pour [*]
..[<selectors>]segment descendant (section 2.5.2) :
sélectionne zéro ou plusieurs descendants d'un nœud
..nameabréviation pour ..['name']
..*abréviation pour ..[*]
'name'sélecteur de nom (section 2.3.1) : sélectionne un
enfant nommé d'un objet
*sélecteur joker (section 2.3.2) : sélectionne
tous les enfants d'un nœud
3sélecteur d'indice (section 2.3.3) : sélectionne un
enfant indexé d'un tableau (à partir de 0)
0💯5sélecteur de tranche (section 2.3.4) :
start:end:step pour les tableaux
?<logical-expr>sélecteur de filtre (section 2.3.5) : sélectionne
des enfants particuliers via une expression
logique
length(@.foo)extension de fonction (section 2.4) : invoque
une fonction dans une expression de filtre

Tableau 1 : Aperçu de la syntaxe JSONPath

1.5. JSONPath Examples (Exemples JSONPath)

Cette section est informative. Elle fournit des exemples d'expressions JSONPath.

Les exemples reposent sur la valeur JSON simple illustrée à la figure 1, représentant une librairie (qui possède aussi un vélo).

{ "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": 399
}
}
}

Figure 1 : Exemple de valeur JSON

Le tableau 2 montre quelques requêtes JSONPath applicables à cet exemple et leurs résultats attendus.

JSONPathRésultat attendu
$.store.book[*].authorles auteurs de tous les livres du magasin
$..authortous les auteurs
$.store.*tout ce qui est dans le magasin, à savoir
des livres et un vélo rouge
$.store..priceles prix de tout ce qui est dans le magasin
$..book[2]le troisième livre
$..book[2].authorl'auteur du troisième livre
$..book[2].publisherrésultat vide : le troisième livre n'a pas
de membre « publisher »
$..book[-1]le dernier livre dans l'ordre
$..book[0,1]les deux premiers livres
$..book[:2]
$..book[[email protected]]tous les livres avec un numéro ISBN
$..book[[email protected]<10]tous les livres à moins de 10
$..*toutes les valeurs de membre et éléments de tableau
contenus dans la valeur d'entrée

Tableau 2 : Exemples d'expressions JSONPath et résultats attendus appliqués à la valeur JSON d'exemple