Gibt es ein JSON-Äquivalent zu XQuery / XPath?


221

Bei der Suche nach Elementen in komplexen JSON-Arrays und -Hashes wie folgt:

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

Gibt es eine Abfragesprache, mit der ich einen Artikel finden kann in [0].objects where id = 3?


nicht, wenn du eins machst. Überlassen Sie die Abfrage dem Server und verwenden Sie REST, um nur die Daten abzurufen, die Sie benötigen.
zzzzBov

5
+1 gute Idee.

2
Nicht XPath, aber ich fand JLinq ziemlich gut (was dazu führt, dass Code wie folgt gelesen wird in(...).where(...).select(...)): hugoware.net/Projects/jLinq .
Pimvdb

4
Das ist frustrierend, weil es viele Bibliotheken gibt, aber nichts, was sich einem allgemein akzeptierten Standard nähert. Wir haben eine Bibliothek, die von Drittanbietern verwendet wird, daher müssen wir eine Abfragesprache bereitstellen, die allgemein bekannt ist und verwendet wird.
David Thielen

1
Sicher, Sie können jsel verwenden - github.com/dragonworx/jsel - vorausgesetzt , Sie haben eine Variable, datadie Ihr JSON-Objekt enthält, würden Sie schreiben: jsel(data).select("//*[@id=3]")und es würde das Objekt mit dem ID-Schlüssel mit 3 zurückgeben.
Ali

Antworten:


122

Ja, es heißt JSONPath . Die Quelle ist jetzt auf GitHub .

Es ist auch in DOJO integriert .


3
Brians Antwort schlägt vor, dass das jsonQuery-Modul anstelle des jsonPath-Moduls im Dojo verwendet werden sollte.
Hugomg

5
Wie solide ist das? Und ich kann keine Java- oder C # -Version finden, die für uns ein Deal Killer ist.
David Thielen

2
Die hier verlinkte Seite bietet Javascript und PHP. Wenn Sie eine Java-Implementierung benötigen, gibt es hier eine: code.google.com/p/json-path
Matthias Ronge

2
Ich sollte erwähnen, dass JSONPath nicht auf der formalen Semantik von XPath basiert. JSONiq könnte eine bessere Option sein.
Wcandillon

1
@Paramaeleon Das funktioniert super. Das Projekt wurde übrigens auf GitHub migriert . Mike möchte dies möglicherweise zur Antwort hinzufügen, da die Leute dies immer wieder kommentieren.
Franklin Yu

21

Ich denke, JSONQuery ist eine Obermenge von JSONPath und ersetzt sie daher im Dojo . Dann gibt es noch RQL .

Aus der Dojo-Dokumentation:

JSONQuery ist eine erweiterte Version von JSONPath mit zusätzlichen Funktionen für Sicherheit, Benutzerfreundlichkeit und einem umfassenden Satz von Datenabfragetools, einschließlich Filterung, rekursiver Suche, Sortierung, Zuordnung, Bereichsauswahl und flexiblen Ausdrücken mit Platzhalterzeichenfolgenvergleichen und verschiedenen Operatoren.

JSONselect hat eine andere Sichtweise auf die Frage (CSS-Selektor-ähnlich statt XPath) und verfügt über eine JavaScript-Implementierung .


4
Der Github-JSONQuery-Link scheint tot zu sein. JSONSelect hat jetzt auch eine JavaScript-Version.
Henrik Aasted Sørensen

19

Andere mir bekannte Alternativen sind

  1. JSONiq- Spezifikation, die zwei Untertypen von Sprachen angibt: einen, der XML-Details verbirgt und JS-ähnliche Syntax bereitstellt, und einen, der die XQuery-Syntax mit JSON-Konstruktoren und dergleichen anreichert. Zorba implementiert JSONiq.
  2. Corona , das auf MarkLogic aufbaut, bietet eine REST-Schnittstelle zum Speichern, Verwalten und Durchsuchen von XML-, JSON-, Text- und Binärinhalten.
  3. MarkLogic 6 und höher bieten eine ähnliche REST-Schnittstelle wie Corona.
  4. MarkLogic 8 und höher unterstützen JSON nativ sowohl in der XQuery- als auch in der serverseitigen JavaScript-Umgebung. Sie können XPath darauf anwenden.

HTH.


3
Es gibt jetzt eine JSONiq-Implementierung: Zorba 2.6 unterstützt sie offiziell.
Ghislain Fourny

Hinweis: MarkLogic speichert JSON nativ ab Version 8 und ermöglicht die direkte Anwendung von XPath.
Grtjn

18

Um einige der aktuellen Optionen zum Durchlaufen / Filtern von JSON-Daten zusammenzufassen und einige Syntaxbeispiele bereitzustellen ...

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

  • json: select () (mehr von CSS-Selektoren inspiriert)
    .automobiles .maker:val("Honda") .model

  • JSONPath (mehr von XPath inspiriert)
    $.automobiles[?(@.maker='Honda')].model

Ich denke, JSPath sieht am besten aus, also werde ich versuchen, es in meine AngularJS + CakePHP-App zu integrieren.

(Ich habe diese Antwort ursprünglich in einem anderen Thread gepostet , dachte aber, dass sie auch hier nützlich wäre.)


Tolle Zusammenfassung und Beispiele, auch weil die Inspiration in CSS-Selektoren oder XPath erwähnt wird.
Jochem Schulenklopper

13

Versuchen Sie, JSPath zu verwenden

JSPath ist eine domänenspezifische Sprache (DSL), mit der Sie in Ihren JSON-Dokumenten navigieren und Daten finden können. Mit JSPath können Sie JSON-Elemente auswählen, um die darin enthaltenen Daten abzurufen.

JSPath für JSON wie ein XPath für XML.

Es ist sowohl für Node.js als auch für moderne Browser stark optimiert.


9

XQuery kann zum Abfragen von JSON verwendet werden, sofern der Prozessor JSON-Unterstützung bietet. Dies ist ein einfaches Beispiel, wie BaseX verwendet werden kann, um Objekte mit "id" = 1 zu finden:

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

(6 Jahre später) Saxon wird XQuery 3.1 ausführen, das JSON abfragt. Meine sächsische Erfahrung ist die Verwendung der von Java ausgeführten JAR-Datei. Es gibt ein Knotenmodul namens saxon-java, aber ich bin mir nicht sicher, wie das mit json funktioniert. Und es gibt noch eine neue Sache von Saxonica namens Saxon-JS.
Charles Ross

9

Gibt es eine Art Abfragesprache ...

jq definiert eine J SON q uery-Sprache, die JSONPath sehr ähnlich ist - siehe https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [welches] kann ich verwenden, um einen Gegenstand in [0] .Objekten zu finden, bei denen id = 3 ist?

Ich gehe davon aus, dass dies bedeutet: Finden Sie alle JSON-Objekte unter dem angegebenen Schlüssel mit der ID == 3, unabhängig davon, wo sich das Objekt befindet. Eine entsprechende jq-Abfrage wäre:

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

wo "|" ist der Pipe-Operator (wie in Befehls-Shell-Pipes) und wobei das Segment ".. | Objekte" "egal wo sich das Objekt befindet" entspricht.

Die Grundlagen von jq sind weitgehend offensichtlich oder intuitiv oder zumindest recht einfach, und der größte Teil des Restes ist leicht zu erlernen, wenn Sie mit Command-Shell-Pipes überhaupt vertraut sind. Die jq- FAQ enthält Hinweise auf Tutorials und dergleichen.

jq ist auch insofern wie SQL, als es CRUD-Operationen unterstützt, obwohl der jq-Prozessor seine Eingabe niemals überschreibt. jq kann auch Streams von JSON-Entitäten verarbeiten.

Zwei weitere Kriterien, die Sie bei der Bewertung einer JSON-orientierten Abfragesprache berücksichtigen sollten, sind:

  • unterstützt es reguläre Ausdrücke? (jq 1.5 bietet umfassende Unterstützung für PCRE-Regex)
  • ist es Turing-vollständig? (ja)

8

Defiant.js sieht auch ziemlich cool aus, hier ein einfaches Beispiel:

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

Leider im Moment nicht auf npm veröffentlicht und erfordert manuelle Installation ...
Andrew Mao


7

Jsel ist großartig und basiert auf einer echten XPath-Engine. Sie können XPath-Ausdrücke erstellen, um alle Arten von JavaScript-Daten zu finden, nicht nur Objekte (auch Zeichenfolgen).

Sie können benutzerdefinierte Schemas und Zuordnungen erstellen, um die vollständige Kontrolle darüber zu erhalten, wie Ihre Daten von der XPath-Engine ausgeführt werden können. Mit einem Schema können Sie definieren, wie Elemente, untergeordnete Elemente, Attribute und Knotenwerte in Ihren Daten definiert werden. Dann können Sie Ihre eigenen Ausdrücke erstellen.

Wenn Sie eine Variable namens aufgerufen haben, datadie den JSON aus der Frage enthält, können Sie mit jsel schreiben:

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

Dies gibt jeden Knoten mit einem idAttribut von 3 zurück. Ein Attribut ist ein beliebiger primitiver Wert (Zeichenfolge, Nummer, Datum, Regex) innerhalb eines Objekts.


6

ObjectPath ist eine Abfragesprache, die XPath oder JSONPath ähnelt, jedoch dank eingebetteter arithmetischer Berechnungen, Vergleichsmechanismen und integrierter Funktionen viel leistungsfähiger ist. Siehe die Syntax:

Finden Sie im Shop alle Schuhe von roter Farbe und Preis unter 50

$ .. Schuhe. * [Farbe ist "rot" und Preis <50]


Ich mag das erste Beispiel auf der Website und es ist großartig, dass ObjectPath in einem interaktiven, Shell-ähnlichen Modus ausgeführt werden kann, aber ich suche nach der Verwendung von ObjectPath in einem Python-Skript. Können Sie mich auf ein Beispiel verweisen, das zeigt, wie ObjectPath als Bibliothek verwendet wird? Ich kann so etwas auf der Website nicht finden.
Piokuc

Bitte lesen Sie den Abschnitt über die Verwendung von Python auf Github . Wir werden dies der Website hinzufügen - es ist im Moment tatsächlich schwer zu finden. Wenn Sie weitere Hilfe benötigen, können Sie eine Frage auf Google Group posten .
Ela Bednarek

Vielen Dank, Ela, die auf der Github-Seite hinzugefügten Beispiele sind genau das, was benötigt wurde.
Piokuc


3

JMESPath scheint heutzutage (ab 2020) sehr beliebt zu sein und behebt eine Reihe von Problemen mit JSONPath. Es ist für viele Sprachen verfügbar.


1

Wenn Sie wie ich sind und nur pfadbasierte Suchvorgänge durchführen möchten, sich aber nicht für echte XPath interessieren, _.get()kann lodash's funktionieren. Beispiel aus lodash docs:

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'

Leider kann diese Funktion nur ein einziges Ergebnis zurückgeben. Sie unterstützt nicht das Abrufen eines Arrays übereinstimmender Elemente. Hier leuchten die anderen Bibliotheken.
Simon East

0

Probieren Sie dies aus - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

Es ist eine sehr einfache Implementierung in einer ähnlichen Zeile von xpath für xml. Es sind Namen wie jpath.


1
Diese Frage ist mit Javascript markiert, aber diese Bibliothek scheint für Java zu sein
Tripleee

Es hat auch eine Javascript-Version - github.com/satyapaul/jpath/blob/master/jpath.js Hier ist die Git-Homepage für das Projekt - github.com/satyapaul/jpath
Satyajit Paul
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.