
JSONPath v10.4.1
Un fork de JSONPath issu de http://goessner.net/articles/JsonPath/
(voir aussi licences pour les dépendances de développement)
JSONPath Plus
Analysez, transformez et extrayez sélectivement des données de documents JSON (et d'objets JavaScript).
jsonpath-plus étend la spécification d'origine en ajoutant quelques
opérateurs supplémentaires et explicite certains comportements que l'original
ne précisait pas.
Essayez la démo navigateur ou Runkit (Node).
Veuillez noter : ce projet n'est actuellement pas maintenu activement. Nous pouvons accepter des PR bien documentées ou quelques mises à jour simples, mais n'envisageons pas de corriger des bogues ni d'ajouter de nouvelles fonctionnalités nous-mêmes.
Fonctionnalités
- Conforme à la spécification jsonpath d'origine
- Ajouts ou précisions pratiques non fournis dans la spécification d'origine :
^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 permettant d'obtenir :
- Les types JSON de base :
@null(),@boolean(),@number(),@string(),@array(),@object() @integer()- Le type composé
@scalar()(qui accepte égalementundefinedet les nombres non finis lors de l'interrogation d'objets JavaScript, ainsi que tous les types de base non-objet/non-fonction) @other()utilisable en conjonction avec unotherTypeCallbackdéfini par l'utilisateur- Les types non-JSON pouvant néanmoins être utilisés lors de l'interrogation
d'objets JavaScript non-JSON (
@undefined(),@function(),@nonFinite())
- Les types JSON de base :
- Raccourcis
@path/@parent/@property/@parentProperty/@rootdans les filtres - Échappement
`pour échapper la séquence restante- Syntaxe
@['...']/?@['...']pour échapper les caractères spéciaux dans les noms de propriétés au sein des filtres
- Documente
$..(obtention de tous les composants parents)
- Formats d'exportation 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 d'origine ou fournir un bac à sable pour les valeurs évaluées.
- Option pour un rappel de gestion des résultats à mesure qu'ils sont obtenus.
Benchmarking
jsonpath-plus est régulièrement performant avec de grands comme de petits ensembles de données par rapport à d'autres bibliothèques d'interrogation JSON, selon json-querying-performance-testing. Vous pouvez vérifier ces résultats en exécutant le projet vous-même et en ajoutant d'autres cas de performance.
Install```shell
npm install jsonpath-plus
## Installation
### 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
astuce Browserify n'est nécessaire :```html
### 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
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 propriété
disponible) 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 à mesure que chaque élément est
découvert, la fonction de rappel étant exécutée 0 à N fois selon
le nombre d'éléments indépendants à trouver dans le résultat.
Consultez la documentation ci-dessous pour en savoir plus sur les arguments
disponibles de JSONPath.
Voir aussi la documentation de l'API.
Propriétés
Les propriétés qui peuvent être fournies sur l'objet options ou sur la
méthode evaluate (comme premier argument) incluent :
- path (obligatoire) - L'expression JSONPath sous forme de chaîne (normalisée ou non) ou de tableau
- json (obligatoire) - L'objet JSON à évaluer (qu'il soit de type null, booléen, nombre, chaîne, objet ou tableau).
- autostart (défaut : true) - Si cette propriété est définie sur
false, on peut appeler la méthodeevaluatemanuellement. - flatten (défaut : false) - Indique si le tableau de résultats renvoyé sera aplati en un tableau à une seule dimension.
- resultType (défaut : "value") - Peut être une forme insensible à la casse de "value", "path", "pointer", "parent" ou "parentProperty" pour déterminer respectivement si les résultats doivent être renvoyés comme valeurs des éléments trouvés, comme leurs chemins absolus, comme pointeurs JSON vers les chemins absolus, comme leurs objets parents, ou comme nom de propriété de leur parent. Si la valeur est "all", tous ces types seront renvoyés sur un objet avec le type comme nom de clé.
- sandbox (défaut : {}) - Tableau de correspondances clé-valeur de variables disponibles pour les évaluations de code telles que les expressions de filtrage. (Notez que le chemin et la valeur courants seront également disponibles pour ces expressions ; voir la section Syntaxe pour plus de détails.)
- wrap (défaut : true) - Indique s'il faut ou non envelopper les résultats
dans un tableau. Si
wrapest défini surfalseet qu'aucun résultat n'est trouvé,undefinedsera renvoyé (par opposition à un tableau vide lorsquewrapest défini sur true). Siwrapest défini surfalseet qu'un seul résultat non-tableau est trouvé, ce résultat sera le seul élément renvoyé (pas dans un tableau). Un tableau sera toutefois toujours renvoyé si plusieurs résultats sont trouvés. Pour éviter les ambiguïtés (dans le cas où il est nécessaire de distinguer un résultat qui est un échec d'un résultat qui est un tableau vide), il est recommandé de passer la valeur par défaut àfalse. - eval (défaut : "safe") - Méthode d'évaluation des scripts.
safe: dans le navigateur, utilise un moteur de script minimal qui n'utilise pasevalniFunctionet satisfait la politique de sécurité du contenu. Dans NodeJS, il n'a aucun effet et équivaut ànativecar les scripts y sont sûrs.native: utilise les capacités de script natives. c'est-à-direevalouFunctionnon sûrs dans le navigateur etvm.Scriptdans 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 appelée aveccodeetcontextcomme arguments pour renvoyer la valeur évaluée.class: une classe créée aveccodecomme argument de constructeur et le code est évalué en appelantrunInNewContextaveccontext. `` - ignoreEvalErrors (défaut : false) - Ignore les erreurs rencontrées pendant l'évaluation des scripts.
- parent (défaut : null) - Dans le cas où une requête pourrait être amenée à renvoyer le nœud racine, cela permet au parent de ce nœud racine d'être renvoyé dans les résultats.
- parentProperty (défaut : null) - Dans le cas où une requête
pourrait être amenée à renvoyer le nœud racine, cela permet à
parentPropertyde ce nœud racine d'être renvoyée dans les résultats. Il peut s'agir d'un nom de propriété sous forme de chaîne ou d'un index de tableau numérique. - callback (défaut : (aucun)) - S'il est fourni, un rappel sera
appelé immédiatement lors de la récupération d'une valeur de point d'extrémité.
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 lesresultTypes). - otherTypeCallback (défaut : <Une fonction qui lève une erreur
lorsque @other() est rencontré>) - En l'absence actuelle de prise en charge
du schéma JSON, 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é,otherTypeCallbacksera invoqué avec la valeur de l'élément, son chemin, son parent et le nom de la propriété de son parent, et il doit renvoyer un booléen indiquant si la valeur fournie appartient au type "other" ou non (ou il peut gérer des transformations et renvoyer false).
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é
autostartest définie surfalse. Elle peut être utilisée pour des évaluations répétées avec la même configuration. Outre les propriétés listées, le second modèle de méthode peut accepter n'importe laquelle des autres propriétés d'instance autorisées (à l'exception deautostartqui n'aurait aucune pertinence ici).
Propriétés et méthodes de classe
- JSONPath.clearCache() - Vide 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 chemins et
le convertit en chaîne de chemin normalisée. La chaîne sera sous une forme
telle que :
$['aProperty']['anotherProperty][0]. Les constructions terminales~et^de JSONPath et les opérateurs de type comme@string()sont silencieusement supprimés. - JSONPath.toPointer(pathAsArray) - Accepte un tableau de chemins et
le convertit en pointeur JSON.
La chaîne sera sous une forme telle que :
/aProperty/anotherProperty/0(avec les caractères internes~et/échappés conformément à la spécification des pointeurs JSON). Les constructions terminales~et^de JSONPath 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 de distinction entre la récupération des éléments et leur contenu textuel (sauf lorsque cela est utile pour des comparaisons ou pour éviter toute ambiguïté). Remarque : pour tester les exemples XPath (y compris ceux en 2.0), cette démo peut être utile (réglez 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 $. comme store.book[*].author (bien que cela ne soit pas présent dans la spécification d'origine) ; notez que certains littéraux de caractères ($ et @) nécessitent un échappement, cependant |
| //author | $..author | Tous les auteurs | |
| /store/* | $.store.* | Tous les éléments du magasin, c'est-à-dire 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)]
$..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 d'origine) |
| //book[position()<3] | $..book[0,1]
$..book[:2] | Les deux premiers livres | |
| //book/*[self::category\|self::author] or //book/(category,author) in XPath 2.0 | $..book[0][category,author] | Les catégories et les auteurs de tous les livres | |
| //book[isbn] | $..book[?(@.isbn)] | Filtre tous les livres avec 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 d'origine) |
| //book[price<10] | $..book[?(@.price<10)] | Filtre tous les livres moins chers que 10 | |
| //*[name() = 'price' and . != 8.95] | $..*[?(@property === 'price' && @ !== 8.95)] | Obtient toutes les valeurs de propriété des objets dont la propriété est price et qui ne sont pas égales à 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 obtenir 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 accent grave |
| //*/*\|//*/*/text() | $..* | Tous les éléments (et le texte) sous la racine d'un document XML. Tous les membres d'une structure JSON sous la racine. | |
| //* | $.. | Tous les éléments d'un document XML. Tous les composants parents d'une structure JSON, y compris la racine. | Ce comportement n'était pas directement spécifié dans la spécification d'origine |
| //*[price>19]/.. | $..[?(@.price>19)]^ | Parent des éléments spécifiques dont le prix est supérieur à 19 (c'est-à-dire la valeur du magasin comme parent du vélo et le tableau de livres comme parent d'un livre individuel) | Parent (caret) non présent dans la spécification d'origine |
| /store/*/name() (in XPath 2.0) | $.store.*~ | Les noms de propriétés du sous-objet du magasin ("book" et "bicycle"). Utile avec les propriétés génériques. | Nom de propriété (tilde) non présent dans la spécification d'origine |
| /store/book[not(. is /store/book[1])] (in XPath 2.0) | $.store.book[?(@path !== "$['store']['book'][0]")] | Tous les livres sauf celui situé au chemin pointant vers le premier | @path n'est pas présent dans la spécification d'origine |
| //book[parent::*/bicycle/color = "red"]/category | $..book[?(@parent.bicycle && @parent.bicycle.color === "red")].category | Récupère toutes les catégories de livres où l'objet parent du livre a un enfant vélo dont la couleur est rouge (c'est-à-dire tous les livres) | @parent n'est pas présent dans la spécification d'origine |
| //book/*[name() != 'category'] | $..book.*[?(@property !== "category")] | Récupère tous les enfants de "book" sauf ceux de type "category" | @property n'est pas présent dans la spécification d'origine |
| //book[position() != 1] | $..book[?(@property !== 0)] | Récupère tous les livres dont la propriété (qui, étant donné que nous atteignons l'intérieur d'un tableau, est l'index numérique) n'est pas 0 | @property n'est pas présent dans la spécification d'origine |
| /store/*/*[name(parent::*) != 'book'] | $.store.*[?(@parentProperty !== "book")] | Récupère les petits-enfants du magasin dont la propriété parente n'est pas book (c'est-à-dire les enfants du vélo, "color" et "price") | @parentProperty n'est pas présent dans la spécification d'origine |
| //book[count(preceding-sibling::*) != 0]/*/text() | $..book.*[?(@parentProperty !== 0)] | Obtient les valeurs de propriété de toutes les instances de livre où la propriété parente de ces valeurs (c'est-à-dire l'index du tableau contenant l'objet parent de l'élément livre) n'est pas 0 | @parentProperty n'est pas présent dans la spécification d'origine |
| //book[price = /store/book[3]/price] | $..book[?(@.price === @root.store.book[2].price)] | Filtre tous les livres dont le prix est égal au prix du troisième livre | @root n'est pas présent dans la spécification d'origine |
| //book/../*[. instance of element(*, xs:decimal)] (in XPath 2.0) | $..book..*@number() | Obtient les valeurs numériques dans le tableau de livres | @number(), les autres types de base (@boolean(), @string()), les autres types dérivés de bas niveau (@null(), @object(), @array()), le type ajouté par JSONSchema, @integer(), le type composé @scalar() (qui accepte également undefined et les nombres non finis pour les objets JavaScript ainsi que tous les types de base non objet/non fonction), le type @other(), à utiliser en conjonction avec un callback défini par l'utilisateur (voir otherTypeCallback) et les types non-JSON suivants qui peuvent néanmoins être utilisés avec JSONPath lors de l'interrogation d'objets JavaScript non-JSON (@undefined(), @function(), @nonFinite()) ne sont pas présents dans la spécification d'origine |
| //book/*[name() = 'category' and matches(., 'tion$')] (XPath 2.0) | $..book.*[?(@property === "category" && @.match(/TION$/i))] | Toutes les catégories de livres qui correspondent à l'expression régulière (se terminent par 'TION' sans tenir compte de la casse) | @property n'est pas présent dans la spécification d'origine. |
| //book/*[matches(name(), 'bn$')]/parent::* (XPath 2.0) | $..book.*[?(@property.match(/bn$/i))]^ | Tous les livres qui ont une propriété correspondant à l'expression régulière (se terminent par 'TION' sans tenir compte de la casse) | @property n'est pas présent dans la spécification d'origine. Remarque : utilise le sélecteur parent ^ à la fin de l'expression pour revenir à l'objet parent ; sans le sélecteur parent, il correspond aux deux valeurs de clé isbn. |
| | ` (par exemple, `$ pour correspondre à une propriété littéralement nommée $) | Échappe toute la séquence suivante (pour être traitée comme un littéral) | ` n'est pas présent dans la spécification d'origine ; pour obtenir un accent grave littéral, utilisez un accent grave supplémentaire pour l'échapper |Toutes les variables supplémentaires fournies en tant que propriétés de l'option d'objet
facultative « sandbox » sont également disponibles pour les évaluations
(basées sur des parenthèses).
Sources potentielles de confusion pour les utilisateurs de XPath
- En JSONPath, une expression de filtre, en plus du fait que son
@soit une référence à ses enfants, sélectionne en réalité les enfants immédiats également, alors qu'en XPath, les conditions de filtre ne sélectionnent pas les enfants mais délimitent lesquels de ses nœuds parents seront obtenus dans le résultat. - En JSONPath, les index de tableau sont, comme en JavaScript, basés sur 0 (ils commencent à 0), alors qu'en XPath, ils sont basés sur 1.
- En JSONPath, les tests d'égalité utilisent (comme en JavaScript) plusieurs signes égal alors qu'en XPath, ils utilisent un seul signe égal.
Interface en ligne de commande
Une interface en ligne de commande (CLI) de base est fournie. Accédez-y en utilisant npx jsonpath-plus <json-file> <jsonpath-query>.
Idées
- Prendre en charge OR en dehors des filtres (comme dans XPath
|) et le regroupement. - Créer une syntaxe qui fonctionne comme les filtres XPath en ne sélectionnant pas les enfants ?
- Permettre une option pour l'équivalent de parentNode (en maintenant toute la chaîne d'objets parent-et-parentProperty jusqu'à la racine)
Développement
Exécution des tests sur Node :```shell npm test
Pour les tests dans le navigateur :
- Servez les fichiers js/html :```shell
npm run browser-test
- Visitez http://localhost:8082/test/.
Sécurité
Veuillez consulter SECURITY.md pour des considérations de sécurité importantes et des instructions sur la manière de signaler des vulnérabilités.