web-dev-qa-db-fra.com

Existe-t-il un équivalent JSON de XQuery/XPath?

Lors de la recherche d'éléments dans des tableaux et des hachages JSON complexes, tels que:

[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [
            // etc.
        }]
    }
]

Existe-t-il un type de langage de requête que je peux utiliser pour trouver un élément in [0].objects where id = 3

195
Naftuli Kay

Eh oui, ça s'appelle JSONPath . La source est maintenant sur GitHub .

Il est également intégré dans DOJO .

113
Mike Christensen

Je pense que JSONQuery est un sur-ensemble de JSONPath et donc le remplace dans dojo . Ensuite, il y a aussi RQL .

De la documentation Dojo:

JSONQuery est une version étendue de JSONPath avec des fonctionnalités supplémentaires pour la sécurité, la facilité d'utilisation et un ensemble complet d'interrogations de données outils incluant le filtrage, la recherche récursive, le tri, la cartographie, la plage sélection et expressions flexibles avec des comparaisons de chaînes génériques et divers opérateurs.

JSONselect a un autre point de vue sur la question (comme un sélecteur CSS, plutôt que XPath) et a une implémentation JavaScript .

20
Brian Clozel

Pour résumer certaines des options actuelles pour parcourir/filtrer les données JSON et fournir des exemples de syntaxe ...

  • JSPath
    .automobiles{.maker === "Honda" && .year > 2009}.model

  • json: select () (plus inspiré par les sélecteurs CSS)
    .automobiles .maker:val("Honda") .model

  • JSONPath (plus inspiré par XPath)
    $.automobiles[?(@.maker='Honda')].model

Je pense que JSPath a l'air le meilleur, alors je vais essayer de l'intégrer à mon application AngularJS + CakePHP.

(Au départ, j'avais posté cette réponse dans n autre fil mais pensais que cela serait utile ici également.)

18
Simon East

Je connais d'autres alternatives

  1. JSONiq spécification, qui spécifie deux sous-types de langages: un qui cache les détails XML et fournit une syntaxe de type JS, et un qui enrichit la syntaxe XQuery de constructeurs JSON, etc. Zorba implémente JSONiq.
  2. Corona , qui repose sur MarkLogic, fournit une interface REST pour stocker, gérer et rechercher du contenu XML, JSON, Texte et binaire.
  3. MarkLogic 6 et versions ultérieures fournissent une interface REST similaire à Corona prête à l'emploi.
  4. MarkLogic 8 et les versions ultérieures prennent en charge JSON de manière native dans leur environnement JavaScript XQuery et Server. Vous pouvez appliquer XPath dessus.

HTH.

15
grtjn

Essayez d'utiliser JSPath

JSPath est un langage spécifique au domaine (DSL) qui vous permet de naviguer et de rechercher des données dans vos documents JSON. À l'aide de JSPath, vous pouvez sélectionner des éléments de JSON afin de récupérer les données qu'ils contiennent.

JSPath for JSON ressemble à un XPath for XML.

Il est fortement optimisé pour Node.js et les navigateurs modernes.

13
dfilatov

XQuery peut être utilisé pour interroger JSON, à condition que le processeur prenne en charge JSON. Voici un exemple simple d'utilisation de BaseX pour trouver des objets avec "id" = 1:

json:parse('[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [ "etc." ] }
    ]}
]')//value[.//id = 1]
9
Christian Grün

Defiant.js a aussi l’air sympa, voici un exemple simple:

var obj = {
        "car": [
            {"id": 10, "color": "silver", "name": "Volvo"},
            {"id": 11, "color": "red",    "name": "Saab"},
            {"id": 12, "color": "red",    "name": "Peugeot"},
            {"id": 13, "color": "yellow", "name": "Porsche"}
        ],
        "bike": [
            {"id": 20, "color": "black", "name": "Cannondale"},
            {"id": 21, "color": "red",   "name": "Shimano"}
        ]
    },
    search = JSON.search(obj, '//car[color="yellow"]/name');

console.log( search );
// ["Porsche"]

var reds = JSON.search(obj, '//*[color="red"]');

for (var i=0; i<reds.length; i++) {
    console.log( reds[i].name );
}
// Saab
// Peugeot
// Shimano
7
Epoc

Json Pointer semble obtenir un soutien croissant aussi.

7
karlfreeman

ObjectPath est un langage de requête similaire à XPath ou JSONPath, mais beaucoup plus puissant grâce aux calculs arithmétiques intégrés, aux mécanismes de comparaison et aux fonctions intégrées

Retrouvez dans la boutique toutes les chaussures de couleur rouge et prix moins de 50

$ .. chaussures. * [la couleur est "rouge" et le prix <50]

6
Ela Bednarek

Jsel est génial et est basé sur un vrai moteur XPath. Il vous permet de créer des expressions XPath pour trouver tout type de données JavaScript, pas seulement des objets (des chaînes aussi).

Vous pouvez créer des schémas et des mappages personnalisés pour vous donner un contrôle complet sur la manière dont vos données peuvent être parcourues par le moteur XPath. Un schéma permet de définir la manière dont les éléments, les enfants, les attributs et les valeurs de nœud sont définis dans vos données. Ensuite, vous pouvez créer vos propres expressions en fonction.

Étant donné que vous aviez une variable appelée data qui contenait le JSON de la question, vous pouvez utiliser jsel pour écrire:

jsel(data).select("//*[@id=3]")

Cela renverra tout nœud avec un attribut id de 3. Un attribut est une valeur primitive (chaîne, nombre, date, expression régulière) d'un objet.

6
Ali

Y a-t-il une sorte de langage de requête ...

jq définit un langage J SON q très similaire à JSONPath - voir https://github.com/stedolan/jq/wiki/For-JSONPath -utilisateurs

... [lequel] je peux utiliser pour trouver un élément dans [0] .objects où id = 3?

Je suppose que cela signifie: recherchez tous les objets JSON sous la clé spécifiée avec id == 3, quel que soit l'endroit où se trouve l'objet. Une requête jq correspondante serait:

.[0].objects | .. | objects | select(.id==3)

où "|" est l'opérateur de pipe (comme dans la commande Shell pipes), et où le segment ".. | objets" correspond à "peu importe où l'objet peut être".

Les bases de jq sont pour la plupart évidentes ou intuitives ou du moins assez simples, et la plupart des autres sont faciles à comprendre si vous êtes du tout familiarisé avec les tubes de commande-shell. Le jq FAQ a des pointeurs sur des tutoriels et autres.

jq est également similaire à SQL en ce sens qu’il prend en charge les opérations CRUD, bien que le processeur jq n’écrase jamais son entrée. jq peut également gérer des flux d'entités JSON.

Deux autres critères à considérer lors de l’évaluation d’un langage de requête orienté JSON sont les suivants:

  • supporte-t-il les expressions régulières? (jq 1.5 offre un support complet pour les regex PCRE)
  • est-ce que c'est Turing-complet? (oui)
5
peak

@Naftule - avec "defiant.js", il est possible d'interroger une structure JSON avec des expressions XPath. Consultez cet évaluateur pour vous faire une idée de son fonctionnement:

http://www.defiantjs.com/#xpath_evaluator

A la différence de JSONPath, "defiant.js" fournit la prise en charge complète de la syntaxe de requête - de XPath sur les structures JSON.

Le code source de defiant.js peut être trouvé ici:
https://github.com/hbi99/defiant.js

4
Hakan Bilgin

Si vous êtes comme moi et que vous souhaitez simplement effectuer des recherches sur les chemins, sans vous soucier du vrai XPath, le _.get() de lodash peut fonctionner. Exemple tiré de la documentation lodash:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, ['a', '0', 'b', 'c']);
// → 3

_.get(object, 'a.b.c', 'default');
// → 'default'
1
adittes

Essayez ceci - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.Java

C'est une implémentation très simple sur une ligne similaire de xpath pour xml. C'est des noms comme jpath.

0
Satyajit Paul