
Un fork de JSONPath issu de http://goessner.net/articles/JsonPath/
[](https://www.npmjs.com/package/jsonpath-plus)
[](badges/tests-badge.svg)
[](badges/coverage-badge.svg)
[](https://snyk.io/test/github/s3u/JSONPath)
<!--[](LICENSE-MIT.txt)-->
[](badges/licenses-badge.svg)
[](https://github.com/JSONPath-Plus/JSONPath/actions/workflows/node.js.yml)
<small>(voir aussi [licences pour les dépendances de développement](https://raw.githubusercontent.com/s3u/JSONPath/master/badges/licenses-badge-dev.svg?sanitize=true))</small>
# JSONPath Plus
Analyser, transformer et extraire sélectivement des données de documents
JSON (et d'objets JavaScript).
`jsonpath-plus` étend la spécification originale pour ajouter quelques
opérateurs supplémentaires et expliciter certains comportements que
l'original ne précisait pas.
Essayez la [démo navigateur](https://jsonpath-plus.github.io/JSONPath/demo/) ou
[Runkit (Node)](https://npm.runkit.com/jsonpath-plus).
***Veuillez noter : ce projet n'est actuellement pas activement maintenu. Nous
pouvons accepter des PR bien documentées ou quelques mises à jour simples, mais
nous ne cherchons pas à apporter des correctifs ou à ajouter de nouvelles
fonctionnalités nous-mêmes.***
## Fonctionnalités
* **Conforme** à la spécification jsonpath originale
* **Ajouts ou précisions** pratiques non fournis dans la spécification originale :
* `^` pour récupérer le **parent** d'un élément correspondant
* `~` pour récupérer les **noms de propriétés** des éléments correspondants (sous forme de tableau)
* **Sélecteurs de type** pour obtenir :
* Les types JSON de base : `@null()`, `@boolean()`, `@number()`, `@string()`, `@array()`, `@object()`
* `@integer()`
* Le type composé `@scalar()` (qui accepte également `undefined` et
les nombres non finis lors de l'interrogation d'objets JavaScript, ainsi que tous les types de base non-objet/non-fonction)
* `@other()` utilisable conjointement avec un `otherTypeCallback` défini par l'utilisateur
* Les types non-JSON qui peuvent néanmoins être utilisés lors de l'interrogation
d'objets JavaScript non-JSON (`@undefined()`, `@function()`, `@nonFinite()`)
* **Sélecteurs raccourcis** `@path`/`@parent`/`@property`/`@parentProperty`/`@root` dans les filtres
* **Échappement**
* `` ` `` pour échapper la séquence restante
* La syntaxe `@['...']`/`?@['...']` pour échapper les caractères spéciaux dans
les noms de propriétés au sein des filtres
* Documente `$..` (**récupération de tous les composants parents**)
* Formats d'export **ESM** et **UMD**
* En plus des valeurs interrogées, **peut renvoyer diverses méta-informations**
notamment les chemins ou pointeurs vers la valeur, ainsi que l'objet
parent et le nom de la propriété parente (pour permettre la modification).
* **Utilitaires de conversion** entre chemins, tableaux et pointeurs
* Option pour **empêcher les évaluations** autorisées dans la spécification originale ou fournir
un **bac à sable** pour les valeurs évaluées.
* Option pour un **callback de gestion des résultats** au fur et à mesure de leur obtention.
## Analyse comparative
`jsonpath-plus` est constamment performant avec des jeux de données grands et petits comparé à d'autres bibliothèques d'interrogation json selon [json-querying-performance-testing](https://github.com/andykais/json-querying-performance-testing). Vous pouvez vérifier ces résultats en [exécutant le projet vous-même](https://github.com/andykais/json-querying-performance-testing#how-to-run) et en ajoutant d'autres cas de performance.
## Installation
```shell
npm install jsonpath-plus
```
## Configuration
### Node.js
```js
const {JSONPath} = require('jsonpath-plus');
const result = JSONPath({path: '...', json});
```
### Navigateur
Pour une utilisation dans le navigateur, vous pouvez inclure directement `dist/index-browser-umd.cjs` ; aucune
magie Browserify n'est nécessaire :
```html
<script src="node_modules/jsonpath-plus/dist/index-browser-umd.cjs"></script>
<script>
const result = JSONPath.JSONPath({path: '...', json: {}});
</script>
```
### ESM (Navigateurs modernes)
Vous pouvez également utiliser les imports de modules ES6 (pour les navigateurs modernes) :
```html
<script type="module">
import {
JSONPath
} from './node_modules/jsonpath-plus/dist/index-browser-esm.js';
const result = JSONPath({path: '...', json: {}});
</script>
```
### ESM (Bundlers)
Ou si vous regroupez votre JavaScript (par exemple, avec Rollup), utilisez simplement,
en notant que [`mainFields`](https://github.com/rollup/plugins/tree/master/packages/node-resolve#mainfields)
devrait inclure `browser` pour les builds navigateur (pour Node, la valeur par défaut, qui
vérifie `module`, devrait convenir) :
```js
import {JSONPath} from 'jsonpath-plus';
const result = JSONPath({path: '...', json});
```
## Utilisation
La signature complète disponible est :
```
const result = JSONPath([options,] path, json, callback, otherTypeCallback);
```
Les arguments `path`, `json`, `callback` et `otherTypeCallback`
peuvent également être exprimés (avec toute autre des
propriétés disponibles) sur `options`.
Notez que `result` contiendra tous les éléments trouvés (éventuellement
enveloppés dans un tableau) tandis que `callback` peut être utilisé si vous
souhaitez effectuer une opération au fur et à mesure que chaque élément est découvert, la
fonction de rappel étant exécutée de 0 à N fois selon
le nombre d'éléments indépendants à trouver dans le résultat.
Voir la documentation ci-dessous pour plus d'informations sur les arguments disponibles de `JSONPath`.
Voir aussi la [documentation de l'API](https://jsonpath-plus.github.io/JSONPath/docs/ts/).
### Propriétés
Les propriétés qui peuvent être fournies sur l'objet options ou
la méthode evaluate (comme premier argument) incluent :
- ***path*** (**requis**) - L'expression JSONPath sous forme de chaîne
(normalisée ou non normalisée) ou de tableau
- ***json*** (**requis**) - L'objet JSON à évaluer (qu'il soit de
type null, boolean, number, string, object ou array).
- ***autostart*** (**par défaut : true**) - Si ceci est fourni comme `false`,
on peut appeler la méthode `evaluate` manuellement.
- ***flatten*** (**par défaut : false**) - Indique si le tableau de résultats retourné
sera aplati en un tableau à une seule dimension.
- ***resultType*** (**par défaut : "value"**) - Peut être une forme insensible à la casse de
"value", "path", "pointer", "parent" ou "parentProperty" pour déterminer
respectivement s'il faut retourner les résultats comme les valeurs des éléments trouvés,
comme leurs chemins absolus, comme [JSON Pointers](https://tools.ietf.org/html/rfc6901)
vers les chemins absolus, comme leurs objets parents, ou comme le nom de propriété
de leur parent. Si défini à "all", tous ces types seront retournés sur
un objet avec le type comme nom de clé.
- ***sandbox*** (**par défaut : {}**) - Table de correspondance clé-valeur des variables à
rendre disponibles pour les évaluations de code telles que les expressions de filtrage. (Notez
que le chemin et la valeur actuels seront également disponibles pour ces
expressions ; voir la section Syntaxe pour plus de détails.)
- ***wrap*** (**par défaut : true**) - Indique s'il faut ou non envelopper les résultats
dans un tableau. Si `wrap` est défini à `false`, et qu'aucun résultat n'est trouvé,
`undefined` sera retourné (par opposition à un tableau vide lorsque
`wrap` est défini à true). Si `wrap` est défini à `false` et qu'un seul
résultat non-tableau est trouvé, ce résultat sera le seul élément retourné
(pas dans un tableau). Un tableau sera toutefois toujours retourné si plusieurs
résultats sont trouvés. Pour éviter les ambiguïtés (dans le cas où
il est nécessaire de distinguer entre un résultat qui est un échec
et un qui est un tableau vide), il est recommandé de passer la
valeur par défaut à `false`.
- ***eval*** (**par défaut : "safe"**) - Méthode d'évaluation de script.
`safe` : Dans le navigateur, il utilisera un moteur de script minimal qui n'utilise pas
`eval` ou `Function` et satisfait la Content Security Policy. Dans NodeJS,
cela n'a aucun effet et est équivalent à native car le scripting y est sûr.
`native` : utilise les capacités de scripting natives. c'est-à-dire `eval` ou
`Function` non sécurisés dans le navigateur et `vm.Script` dans nodejs. `false` : Désactive les expressions
d'évaluation JavaScript et lève des exceptions lorsque ces expressions sont tentées.
`callback [ (code, context) => value]` : Une implémentation personnalisée qui est appelée
avec `code` et `context` comme arguments pour retourner la valeur évaluée.
`class` : Une classe qui est créée avec `code` comme argument de constructeur et le code
est évalué en appelant `runInNewContext` avec `context`.
``
- ***ignoreEvalErrors*** (**par défaut : false**) - Ignore les erreurs rencontrées lors de
l'évaluation de script.
- ***parent*** (**par défaut : null**) - Dans le cas où une requête pourrait
être faite pour retourner le nœud racine, ceci permet au parent de ce nœud racine
d'être retourné dans les résultats.
- ***parentProperty*** (**par défaut : null**) - Dans le cas où une requête
pourrait être faite pour retourner le nœud racine, ceci permet à la `parentProperty`
de ce nœud racine d'être retournée dans les résultats. Cela peut être un nom de propriété
de type chaîne ou un index de tableau numérique.
- ***callback*** (**par défaut : (aucun)**) - Si fourni, un callback sera
appelé immédiatement lors de la récupération d'une valeur de point final. Les trois arguments
fournis seront la valeur de la charge utile (selon `resultType`),
le type de la charge utile (qu'il s'agisse d'une "value" normale ou d'un nom de
"property"), et un objet de charge utile complet (avec tous les `resultType`s).
- ***otherTypeCallback*** (**par défaut : \<Une fonction qui lève une erreur**
**lorsque @other() est rencontré\>**) - En l'absence actuelle de support de JSON
Schema, on peut déterminer des types au-delà des types intégrés en
ajoutant l'opérateur `@other()` à la fin de sa requête. Si un tel
chemin est rencontré, le `otherTypeCallback` sera invoqué avec la
valeur de l'élément, son chemin, son parent, et le nom de propriété de son parent,
et il devrait retourner un booléen indiquant si la valeur fournie
appartient au type "other" ou non (ou il peut gérer des transformations et
retourner false).
- ***customTypes*** (**par défaut : {}**) - Une table de correspondance clé-valeur des noms de types vers des fonctions.
Cela permet de créer des opérateurs de type personnalisés qui peuvent être utilisés dans les requêtes
(par exemple, `@myType()`). La fonction sera invoquée avec la valeur de l'élément,
son chemin, son parent, et le nom de propriété de son parent. Elle devrait retourner un
booléen indiquant si la valeur fournie correspond au type personnalisé. Peut
également être défini à :
1. La valeur de l'import `jsonpath-plus/src/structuredCloningTypes.js` qui prédéfinit les types suivants :
@NaN(), @BigIntObject(), @Date(), @Set(), @Map(), @RegExp(),
@Blob(optionalMimeType), @File(optionalMimeType), @Boolean(), @Number(),
@String(), @Infinity(), @negativeInfinity(), @negativeZero(),
@DOMException(), @Error(), @EvalError(), @RangeError(), @ReferenceError(),
@SyntaxError(), @TypeError(), @URIError(), @AggregateError(),
@QuotaExceededError(), @WebTransportError(), @FileList, @ArrayBuffer(),
@DataView(), @ImageData(), @ImageBitmap(), @Int8Array(), @Uint8Array(),
@Uint8ClampedArray(), @Int16Array(), @Uint16Array(), @Int32Array(),
@Uint32Array(), @Float32Array(), @Float64Array(), @BigInt64Array(),
@BigUint64Array(), @Float16Array, @DOMMatrix(), @DOMMatrixReadOnly(),
@DOMPoint(), @DOMPointReadOnly(), @DOMRect, @DOMRectReadOnly(),
@DOMQuad(), @CryptoKey(), @AudioData(), @EncodedAudioChunk(),
@EncodedVideoChunk(), @VideoFrame(), @CropTarget,
@FileSystemDirectoryHandle(), @FileSystemFileHandle(),
@GPUCompilationInfo(), @GPUCompilationMessage(),
@GPUPipelineError(), @RTCCertificate(), @RTCEncodedAudioFrame(),
@RTCEncodedVideoFrame()
2. La valeur de l'import `jsonpath-plus/src/javascriptTypes.js` qui prédéfinit les types suivants :
@Generator(), @AsyncGenerator(), @GeneratorFunction(),
@AsyncGeneratorFunction(), @Iterable(), @AsyncIterable(), @Iterator()
### Méthodes d'instance
- ***evaluate(path, json, callback, otherTypeCallback)*** OU
***evaluate({path: \<path\>, json: \<json object\>, callback:***
***\<callback function\>, otherTypeCallback:***
***\<otherTypeCallback function\>})*** - Cette méthode n'est
nécessaire que si la propriété `autostart` est définie à `false`. Elle
peut être utilisée pour des évaluations répétées en utilisant la même configuration.
Outre les propriétés listées, le dernier modèle de méthode peut
accepter n'importe laquelle des autres propriétés d'instance autorisées (sauf
`autostart` qui n'aurait aucune pertinence ici).
### Propriétés et méthodes de classe
- ***JSONPath.clearCache()*** - Efface les chemins analysés et les scripts compilés
mis en cache en interne. Le contenu du cache n'est pas exposé ; appelez cette méthode lorsque
l'invalidation du cache est nécessaire.
- ***JSONPath.toPathArray(pathAsString)*** - Accepte un chemin normalisé ou
non normalisé sous forme de chaîne et le convertit en tableau : par
exemple, `['$', 'aProperty', 'anotherProperty']`.
- ***JSONPath.toPathString(pathAsArray)*** - Accepte un tableau de chemin et
le convertit en une chaîne de chemin normalisée. La chaîne sera sous une forme
comme : `$['aProperty']['anotherProperty][0]`. Les constructions terminales JSONPath
`~` et `^` et les opérateurs de type comme `@string()` sont
silencieusement supprimés.
- ***JSONPath.toPointer(pathAsArray)*** - Accepte un tableau de chemin et
le convertit en un [JSON Pointer](https://tools.ietf.org/html/rfc6901).
La chaîne sera sous une forme comme : `/aProperty/anotherProperty/0`
(avec tous les caractères internes `~` et `/` échappés conformément à la spécification JSON
Pointer). Les constructions terminales JSONPath `~` et `^` et
les opérateurs de type comme `@string()` sont silencieusement supprimés.
## Syntaxe à travers des exemples
Étant donné le JSON suivant, tiré de <http://goessner.net/articles/JsonPath/> :
```json
{
"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
}
}
}
```
et la représentation XML suivante :
```xml
<store>
<book>
<category>reference</category>
<author>Nigel Rees</author>
<title>Sayings of the Century</title>
<price>8.95</price>
</book>
<book>
<category>fiction</category>
<author>Evelyn Waugh</author>
<title>Sword of Honour</title>
<price>12.99</price>
</book>
<book>
<category>fiction</category>
<author>Herman Melville</author>
<title>Moby Dick</title>
<isbn>0-553-21311-3</isbn>
<price>8.99</price>
</book>
<book>
<category>fiction</category>
<author>J. R. R. Tolkien</author>
<title>The Lord of the Rings</title>
<isbn>0-395-19395-8</isbn>
<price>22.99</price>
</book>
<bicycle>
<color>red</color>
<price>19.95</price>
</bicycle>
</store>
```
Veuillez noter que les exemples XPath ci-dessous ne font pas la distinction entre
la récupération des éléments et de leur contenu textuel (sauf lorsque cela est utile pour
les comparaisons ou pour éviter toute ambiguïté). Remarque : pour tester les exemples XPath
(y compris ceux de la version 2.0), [cette démo](http://videlibri.sourceforge.net/cgi-bin/xidelcgi)
peut être utile (définie sur `xml` ou `xml-strict`).
| XPath | JSONPath | Résultat | Notes |
|-------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `/store/book/author` | `$.store.book[*].author` | Les auteurs de tous les livres du magasin | Peut également être représenté sans le `$.` comme `store.book[*].author` (bien que cela ne soit pas présent dans la spécification originale) ; notez que certains caractères littéraux (`$` et `@`) nécessitent un échappement, cependant |
| `//author` | `$..author` | Tous les auteurs | |
| `/store/*` | `$.store.*` | Toutes les choses dans le magasin, qui sont ses livres (un tableau de livres) et un vélo rouge (un objet vélo). | |
| `/store//price` | `$.store..price` | Le prix de tout ce qui se trouve dans le magasin. | |
| `//book[3]` | `$..book[2]` | Le troisième livre (objet livre) | |
| `//book[last()]` | `$..book[(@.length-1)]` <br> `$..book[-1:]` | Le dernier livre dans l'ordre. | Pour accéder à une propriété avec un caractère spécial, utilisez `[(@['...'])]` pour le filtre (cette fonctionnalité particulière n'est pas présente dans la spécification originale) |
| `//book[position()<3]` | `$..book[0,1]` <br> `$..book[:2]` | Les deux premiers livres | |
| `//book/*[self::category\|self::author]` ou `//book/(category,author)` en XPath 2.0 | `$..book[0][category,author]` | Les catégories et les auteurs de tous les livres | |
| `//book[isbn]` | `$..book[?(@.isbn)]` | Filtrer tous les livres ayant un numéro ISBN | Pour accéder à une propriété avec un caractère spécial, utilisez `[?@['...']]` pour le filtre (cette fonctionnalité particulière n'est pas présente dans la spécification originale) |
| `//book[price<10]` | `$..book[?(@.price<10)]` | Filtrer tous les livres moins chers que 10 | |
| `//*[name() = 'price' and . != 8.95]` | `$..*[?(@property === 'price' && @ !== 8.95)]` | Obtenir toutes les valeurs de propriété des objets dont la propriété est price et qui n'est pas égale à 8.95 | Avec le `@` seul permettant de filtrer les objets par valeur de propriété (pas nécessairement dans des tableaux), vous pouvez ajouter `^` après l'expression pour accéder à l'objet possédant les propriétés filtrées |
| `/` | `$` | La racine de l'objet JSON (c'est-à-dire l'objet entier lui-même) | Pour obtenir un `$` littéral (seul ou n'importe où dans le chemin), vous devez utiliser l'échappement par backtick |
| `//*/*\|//*/*/text()` | `$..*` | Tous les éléments (et texte) sous la racine dans un document XML. Tous les membres d'une structure JSON sous la racine. | |
---
[Read more](https://github.com/jsonpath-plus/jsonpath)