JSONPath-Abfrageleitfaden: So durchsuchen Sie JSON-Daten
JSON ist zur universellen Sprache des Webs geworden. APIs geben JSON zurück, Konfigurationsdateien verwenden JSON und Datenbanken speichern JSON-Dokumente. Aber je größer und tiefer verschachtelt JSON-Strukturen werden, desto schwieriger wird es, bestimmte Werte zu finden. Hier kommt JSONPath ins Spiel. JSONPath ist eine Abfragesprache, mit der Sie JSON-Dokumente mithilfe prägnanter Pfadausdrücke navigieren und Daten extrahieren können – ähnlich wie XPath für XML. Dieser Leitfaden behandelt alles von der grundlegenden Syntax bis zur erweiterten Filterung, mit praktischen Beispielen, die Sie sofort anwenden können.
Was ist JSONPath?
JSONPath ist eine JSON-Abfragesprache, die ursprünglich 2007 von Stefan Goessner vorgeschlagen wurde. Sie bietet eine kompakte Syntax zur Auswahl von Knoten aus JSON-Dokumenten, ähnlich wie CSS-Selektoren HTML-Elemente oder XPath-Ausdrücke XML-Knoten ansprechen. Anstatt Schleifen und bedingte Logik zum Durchlaufen von JSON-Strukturen zu schreiben, schreiben Sie einfach einen Ausdruck, der den Pfad zu den gewünschten Daten beschreibt.
JSONPath-Ausdrücke beginnen am Wurzelknoten des JSON-Dokuments und navigieren durch Objekte und Arrays zu den gewünschten Werten. Die Sprache unterstützt Platzhalter, rekursiven Abstieg, Array-Slicing und Filterausdrücke, die für die meisten Datenextraktionsanforderungen ausreichen.
Beispiel-JSON-Dokument
In diesem Leitfaden verwenden wir das folgende JSON-Dokument als Arbeitsbeispiel. Dies ist das klassische Beispiel aus dem ursprünglichen JSONPath-Vorschlag, ergänzt um zusätzliche Daten:
{
"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
}
}
}JSONPath-Syntaxreferenz
JSONPath verwendet einen kleinen Satz von Operatoren, die zu leistungsstarken Abfragen kombiniert werden. Hier ist die vollständige Syntaxreferenz:
| Operator | Beschreibung | Beispiel |
|---|---|---|
| $ | Wurzelknoten des Dokuments | $ |
| . | Kind-Operator (Zugriff auf Objekteigenschaften) | $.store |
| [] | Array-Index oder Kind-Operator | $.store.book[0] |
| [*] | Platzhalter für alle Array-Elemente | $.store.book[*] |
| .. | Rekursiver Abstieg (alle Ebenen durchsuchen) | $..author |
| .key | Benannte Objekteigenschaft | $.store.bicycle |
| ['key'] | Klammernotation für Eigenschaftszugriff | $['store']['book'] |
| [start:end] | Array-Slicing (Endindex exklusiv) | $.store.book[0:2] |
| [?()] | Filterausdruck | < 10)] |
| () | Skriptausdruck (implementierungsabhängig) | $.store.book[(@.length-1)] |
Grundlegende JSONPath-Ausdrücke
Zugriff auf Wurzelknoten und direkte Kinder
Das Dollarzeichen $ repräsentiert den Wurzelknoten des JSON-Dokuments. Von dort aus verwenden Sie die Punktnotation für den Zugriff auf Objekteigenschaften und die Klammernotation für den Zugriff auf Array-Indizes.
| Ausdruck | Ergebnis |
|---|---|
| $ | Gesamtes JSON-Dokument |
| $.store | Das store-Objekt (enthält book-Array und bicycle-Objekt) |
| $.store.bicycle | {"color": "red", "price": 19.95} |
| $.store.bicycle.color | "red" |
| $.store.book | Das gesamte book-Array |
| $.store.book[0] | Das erste Buch-Objekt |
| $.store.book[0].title | "Sayings of the Century" |
| $.store.book[3].author | "J.R.R. Tolkien" |
Klammernotation
Die Klammernotation ist eine Alternative zur Punktnotation und nützlich, wenn Eigenschaftsnamen Sonderzeichen, Leerzeichen enthalten oder mit einer Ziffer beginnen:
$.store['book'][0]['title']
$['store']['bicycle']['color']Klammernotation und Punktnotation sind für Objekteigenschaften austauschbar. Wenn der Eigenschaftsname jedoch dynamisch ist oder Zeichen enthält, die in der Punktnotation ungültig sind, muss die Klammernotation verwendet werden.
Platzhalter-Operatoren
Der Platzhalter-Operator * entspricht allen Elementen in einem Array oder allen Eigenschaften in einem Objekt. Er ist äußerst nützlich, um alle Werte auf einer bestimmten Ebene zu extrahieren, ohne die spezifischen Schlüssel oder Indizes zu kennen.
| Ausdruck | Ergebnis |
|---|---|
| $.store.* | Alle Werte im store-Objekt (book-Array und bicycle-Objekt) |
| $.store.book[*] | Alle Bücher im Array (alle vier book-Objekte) |
| $.store.book[*].author | Alle Autorennamen: ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"] |
| $.store.*.price | Preis des bicycle und das book-Array (nicht die Preise einzelner Bücher) |
Rekursiver Abstieg: Der Doppelpunkt-Operator
Der Doppelpunkt-Operator .. ist eine der leistungsfähigsten Funktionen von JSONPath. Er durchsucht jede Ebene des JSON-Baums nach dem angegebenen Schlüssel, nicht nur die direkten Kinder. Stellen Sie sich dies als eine Tiefensuche im gesamten Dokument vor.
| Ausdruck | Ergebnis |
|---|---|
| $..author | Alle author-Werte an beliebiger Stelle im Dokument |
| $..price | Alle price-Werte: [8.95, 12.99, 8.99, 22.99, 19.95] |
| $..book[2] | Das dritte Buch, rekursiv gefunden |
| $..category | Alle category-Werte: ["reference", "fiction", "fiction", "fiction"] |
Der rekursive Abstiegsoperator ist besonders nützlich, wenn Sie den genauen Pfad zu den gewünschten Daten nicht kennen oder wenn derselbe Schlüssel auf mehreren Verschachtelungsebenen vorkommt. Wenn beispielsweise eine API-Antwort id-Felder auf verschiedenen Verschachtelungsebenen enthält, sammelt $..id alle IDs.
Array-Slicing
Array-Slicing ermöglicht es Ihnen, einen Bereich von Elementen aus einem Array auszuwählen. Die Syntax [start:end] wählt Elemente vom Startindex bis (aber nicht einschließlich) zum Endindex aus. Sowohl positive als auch negative Indizes werden unterstützt.
| Ausdruck | Ergebnis |
|---|---|
| $.store.book[0:2] | Die ersten beiden Bücher (Indizes 0 und 1) |
| $.store.book[1:3] | Das zweite und dritte Buch (Indizes 1 und 2) |
| $.store.book[-1] | Das letzte Buch (The Lord of the Rings) |
| $.store.book[-2:] | Die letzten beiden Bücher |
| $.store.book[:2] | Die ersten beiden Bücher (wie [0:2]) |
| $.store.book[2:] | Das dritte Buch und alle danach |
Beachten Sie, dass das Slicing-Verhalten zwischen verschiedenen JSONPath-Implementierungen leicht variieren kann. Die obige Syntax folgt der Konvention, die von den meisten gängigen Bibliotheken und dem IETF RFC 9535-Standard verwendet wird.
Filterausdrücke
Filterausdrücke sind der Bereich, in dem JSONPath wirklich leistungsfähig wird. Sie ermöglichen es Ihnen, Elemente basierend auf Bedingungen statt auf Position auszuwählen. Die Filtersyntax verwendet [?(condition)], wobei die Bedingung für jedes Element ausgewertet wird.
Vergleichsoperatoren
JSONPath unterstützt die folgenden Vergleichsoperatoren in Filterausdrücken:
| Operator | Bedeutung | Beispiel |
|---|---|---|
| == | Gleich | [?(@.category == "fiction")] |
| != | Ungleich | [?(@.category != "fiction")] |
| < | Kleiner als | < 10)] |
| <= | Kleiner oder gleich | <= 8.99)] |
| > | Größer als | [?(@.price > 15)] |
| >= | Größer oder gleich | [?(@.price >= 12.99)] |
| =~ | Regex-Übereinstimmung (teilweise implementiert) | [?(@.author =~ /Tolkien/i)] |
Praktische Filterbeispiele
Unter Verwendung unseres Beispieldokuments sind hier praktische Filterausdrücke und ihre Ergebnisse:
Find all books cheaper than $10:
< 10)]Gibt die Bücher „Sayings of the Century" ($8,95) und „Moby Dick" ($8,99) zurück.
Find all fiction books:
$.store.book[?(@.category == "fiction")]Gibt drei Bücher zurück: „Sword of Honour", „Moby Dick" und „The Lord of the Rings".
Find books with an ISBN:
$.store.book[?(@.isbn)]Gibt Bücher mit einer isbn-Eigenschaft zurück: „Moby Dick" und „The Lord of the Rings". Dies liegt daran, dass der Filter prüft, ob die Eigenschaft vorhanden ist.
Find the most expensive book:
$.store.book[?(@.price > 20)]Gibt „The Lord of the Rings" ($22,99) zurück.
Logische Operatoren in Filtern
Sie können Bedingungen mit logischen Operatoren kombinieren:
< 10 && @.category == "fiction")]
$.store.book[?(@.price > 15 || @.category == "reference")]Der erste Ausdruck findet Romane unter 10 $ (nur „Moby Dick"). Der zweite findet Bücher, die über 15 $ kosten oder zur Kategorie Referenz gehören (gibt „Sayings of the Century" und „The Lord of the Rings" zurück).
JSONPath vs. XPath
JSONPath ist explizit XPath nachempfunden, und die beiden Sprachen haben viele konzeptionelle Ähnlichkeiten. Wenn Sie mit der XML-Verarbeitung vertraut sind, hilft das Verständnis dieser Beziehung.
| Funktion | JSONPath | XPath |
|---|---|---|
| Wurzelzeichen | $ | / |
| Kindzugriff | .key oder ['key'] | /element |
| Array-Index | [0] | [1] (beginnt bei 1) |
| Platzhalter | * | * |
| Rekursiver Abstieg | .. | // |
| Filter | [?(condition)] | [condition] |
| Attribut | Nicht zutreffend (JSON hat keine Attribute) | @attr |
| Aktueller Knoten | @ (in Filtern) | . oder current() |
| Eltern | Nicht unterstützt | .. |
| Achse | Nicht unterstützt | 13 Achsen (ancestor, following usw.) |
| Datenmodell | Objekte und Arrays | Elemente, Attribute, Textknoten |
Der Hauptunterschied besteht darin, dass XPath auf einem reichhaltigen Baummodell mit Elementen, Attributen, Textknoten, Namespaces und Verarbeitungsanweisungen operiert. JSONPath operiert auf einem einfacheren Modell von Objekten (Schlüssel-Wert-Zuordnungen) und Arrays (geordnete Listen). Diese Einfachheit macht JSONPath leichter zu erlernen, aber weniger ausdrucksstark als XPath für komplexe Abfragen.
JSONPath in der Praxis
API-Tests
JSONPath ist für API-Tests unverzichtbar. Wenn Sie eine Anfrage an eine API senden und eine große JSON-Antwort erhalten, können Sie mit JSONPath bestimmte Werte bestätigen, ohne die gesamte Struktur manuell navigieren zu müssen. Die meisten API-Testwerkzeuge unterstützen JSONPath nativ.
Zum Beispiel könnten Sie in einem Test überprüfen, ob der Preis des ersten Buches unter 10 $ liegt:
// Using a JSONPath assertion in testing
response.jsonPath().get("store.book[0].price").should(equals(8.95));
// Find all books by a specific author
response.jsonPath().get("store.book[?(@.author == 'Herman Melville')].title");
// Returns: ["Moby Dick"]Datentransformation
Bei der Integration von Systemen, die unterschiedliche Datenformate verwenden, hilft JSONPath beim Extrahieren und Transformieren bestimmter Felder. Sie können Werte aus einer JSON-Struktur extrahieren und in eine andere abbilden, ohne komplexen Traversierungscode schreiben zu müssen.
Konfigurationsverwaltung
Komplexe Konfigurationsdateien enthalten oft tief verschachteltes JSON. Mit JSONPath können Sie bestimmte Konfigurationswerte abfragen, ohne die gesamte Struktur laden und parsen zu müssen. Tools wie jq verwenden eine JSONPath-ähnliche Syntax, um JSON in Kommandozeilen-Pipelines zu verarbeiten.
Überwachung und Alarmierung
In Observability-Systemen können JSONPath-Abfragen Metriken aus JSON-formatierten Protokollen und API-Antworten extrahieren. Sie können Alarme einrichten, die ausgelöst werden, wenn eine JSONPath-Abfrage einen Wert zurückgibt, der einen Schwellenwert überschreitet.
JSONPath-Implementierungen
JSONPath ist in fast jeder Programmiersprache verfügbar. Hier sind die beliebtesten Bibliotheken:
| Sprache | Bibliothek | Installation |
|---|---|---|
| JavaScript | jsonpath-plus | npm install jsonpath-plus |
| Python | jsonpath-ng | pip install jsonpath-ng |
| Java | JsonPath (Jayway) | Maven: com.jayway.jsonpath |
| C# | Json.NET (Newtonsoft) | NuGet: Newtonsoft.Json |
| Go | gjson | go get github.com/tidwall/gjson |
| PHP | jsonpath | composer require softcreatr/jsonpath |
| Ruby | jsonpath | gem install jsonpath |
JavaScript-Beispiel
< 10)]',
json: data
});
// Returns books with price < 10
Python Example
from jsonpath_ng import parse
data = { /* our sample JSON */ }
# Find all authors
author_expr = parse('$..author')
authors = [match.value for match in author_expr.find(data)]
# ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"]
# Find cheap books
cheap_expr = parse('$.store.book[?(@.price < 10)]')
cheap_books = [match.value for match in cheap_expr.find(data)]
Common Pitfalls and Tips
- Zero-based vs one-based indexing: JSONPath uses zero-based indexing (the first element is [0]), while XPath uses one-based indexing (the first element is [1]). This is a common source of off-by-one errors.
- Implementation differences: Before the IETF standard (RFC 9535), JSONPath implementations varied in their handling of edge cases like empty results, null values, and filter syntax. Always test your expressions with the specific library you are using.
- Filter performance: Recursive descent with filters (
$..book[?(@.price < 10)]) can be slow on large documents because it must traverse the entire tree. For performance-critical applications, use more specific paths when possible. - Case sensitivity: JSONPath is case-sensitive.
$.Storewill not match$.store. This is consistent with JSON's case-sensitive nature. - Nullbasierte vs. einsbasierte Indizierung: JSONPath verwendet nullbasierte Indizierung (das erste Element ist [0]), während XPath einsbasierte Indizierung verwendet (das erste Element ist [1]). Dies ist eine häufige Quelle für Off-by-one-Fehler.
- Implementierungsunterschiede: Vor dem IETF-Standard (RFC 9535) unterschieden sich JSONPath-Implementierungen in der Behandlung von Randfällen wie leeren Ergebnissen, null-Werten und Filtersyntax. Testen Sie Ausdrücke immer mit Ihrer spezifischen Bibliothek.
Häufige Fallstricke und Tipps
Im Jahr 2024 veröffentlichte die IETF RFC 9535, der JSONPath formell standardisiert. Die Spezifikation behebt viele Unklarheiten und Inkonsistenzen zwischen den Implementierungen. Zu den wichtigsten Aspekten des Standards gehören:
- < 10)]) kann bei großen Dokumenten langsam sein, da er den gesamten Baum durchlaufen muss. Verwenden Sie für leistungskritische Anwendungen nach Möglichkeit spezifischere Pfade.
- Groß-/Kleinschreibung: JSONPath unterscheidet zwischen Groß- und Kleinschreibung. $.Store entspricht nicht $.store. Dies steht im Einklang mit der Groß-/Kleinschreibung von JSON.
- Sonderzeichen escapen: Wenn Schlüsselnamen Punkte oder Klammern enthalten, müssen Sie die Klammernotation mit Anführungszeichen verwenden: $['key.with.dots'] statt $.key.with.dots.
- Keine Eltern-Traversierung: Im Gegensatz zu XPath kann JSONPath nicht zum Elternknoten navigieren. Es gibt kein Äquivalent zum .. (Elternachse) von XPath. Das .. von JSONPath steht für rekursiven Abstieg, nicht für die Elternachse.
Wenn Sie ein neues Projekt starten, bevorzugen Sie Bibliotheken, die RFC 9535 implementieren, für maximale Kompatibilität und vorhersagbares Verhalten.
Müssen Sie schnell JSON-Daten abfragen? Probieren Sie unseren kostenlosen Online-JSONPath-Tester aus, um Ausdrücke in Echtzeit gegen Ihre JSON-Dokumente auszuwerten.
JSONPath-Finder ausprobierenIETF-Standard: RFC 9535
Python-Beispiel
JSONPath ist eine JSON-Abfragesprache, ähnlich wie XPath für XML. Sie verwendet Pfadausdrücke, um bestimmte Werte in JSON-Dokumenten zu navigieren und zu extrahieren. Ein JSONPath-Ausdruck wie $.store.book[0].title ermöglicht es Ihnen, Daten in komplexen, verschachtelten JSON-Strukturen präzise zu lokalisieren, ohne benutzerdefinierten Parsing-Code schreiben zu müssen.
Was ist JSONPath?
JSONPath ist für die Objekt- und Array-Struktur von JSON konzipiert, während XPath für die Element- und Attributstruktur von XML konzipiert ist. JSONPath verwendet $ als Wurzelknoten, Punktnotation für den Objektzugriff und Klammernotation für den Array-Zugriff. XPath verwendet / als Pfadtrennzeichen und @ für den Attributzugriff. JSONPath ist einfacher, aber weniger funktionsreich als XPath.
Wie unterscheidet sich JSONPath von XPath?
Der Doppelpunkt (..) in JSONPath ist der rekursive Abstiegsoperator. Er durchsucht alle Ebenen der JSON-Struktur nach dem benannten Schlüssel, nicht nur die direkten Kinder. Zum Beispiel findet $..author alle author-Schlüssel an beliebiger Stelle im gesamten Dokument, unabhängig davon, wie tief sie verschachtelt sind.
Was bedeutet der Doppelpunkt (..) in JSONPath?
<, ><=, >< 10)] alle Bücher unter 10 $.
Kann JSONPath Daten nach Bedingungen filtern?
JSONPath wurde ursprünglich 2007 von Stefan Goessner ohne formale Spezifikation vorgeschlagen, was zu Unterschieden zwischen den Implementierungen führte. Im Jahr 2024 veröffentlichte die IETF RFC 9535 zur formellen Standardisierung von JSONPath. Moderne Implementierungen konvergieren auf diesen Standard, aber einige ältere Bibliotheken können noch geringfügige Syntaxunterschiede aufweisen.