JSONPath Query-gids: JSON-gegevens doorzoeken
JSON is de universele taal van het web geworden. API's retourneren JSON, configuratiebestanden gebruiken JSON en databases slaan JSON-documenten op. Maar naarmate JSON-structuren groter en dieper genest worden, wordt het steeds moeilijker om specifieke waarden te vinden. Dat is waar JSONPath om de hoek komt kijken. JSONPath is een querytaal waarmee u door JSON-documenten kunt navigeren en er gegevens uit kunt halen met beknopte pad-expressies, net als XPath dat doet voor XML. Deze gids behandelt alles van basissyntaxis tot geavanceerd filteren, met praktische voorbeelden die u direct kunt toepassen.
Wat is JSONPath?
JSONPath is een querytaal voor JSON die oorspronkelijk in 2007 werd voorgesteld door Stefan Goessner. Het biedt een compacte syntaxis voor het selecteren van nodes uit een JSON-document, vergelijkbaar met hoe CSS-selectors HTML-elementen targeten of XPath-expressies XML-nodes lokaliseren. In plaats van lussen en voorwaardelijke logica te schrijven om een JSON-structuur te doorlopen, schrijft u één expressie die het pad naar de gewenste gegevens beschrijft.
JSONPath-expressies beginnen bij de root van het JSON-document en navigeren door objecten en arrays om de gewenste waarden te bereiken. De taal ondersteunt wildcards, recursieve afdaling, array-slicing en filterexpressies, wat het krachtig genoeg maakt voor de meeste gegevensextractiebehoeften.
Het voorbeeld-JSON-document
Door deze gids zullen we het volgende JSON-document gebruiken als werkend voorbeeld. Dit is het klassieke voorbeeld uit het oorspronkelijke JSONPath-voorstel, aangepast met aanvullende gegevens:
{
"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-syntaxisreferentie
JSONPath gebruikt een kleine set operatoren die combineren tot krachtige query's. Hier is de volledige syntaxisreferentie:
| Operator | Beschrijving | Voorbeeld |
|---|---|---|
| $ | Root-node van het document | $ |
| . | Child-operator (objecteigenschap benaderen) | $.store |
| [] | Array-index of child-operator | $.store.book[0] |
| [*] | Wildcard voor alle array-elementen | $.store.book[*] |
| .. | Recursieve afdaling (alle niveaus doorzoeken) | $..author |
| .key | Benoemde objecteigenschap | $.store.bicycle |
| ['key'] | Haakjesnotatie voor eigenschapstoegang | $['store']['book'] |
| [start:end] | Array-slice (eind is exclusief) | $.store.book[0:2] |
| [?()]code> | Filterexpressie | < 10)] |
| () | Script-expressie (implementatie-afhankelijk) | $.store.book[(@.length-1)] |
Basis JSONPath-expressies
De root en directe children benaderen
Het dollarteken $ vertegenwoordigt de root van het JSON-document. Van daaruit navigeert u met puntnotatie voor objecteigenschappen en haakjesnotatie voor array-indices.
| Expressie | Resultaat |
|---|---|
| $ | Het hele JSON-document |
| $.store | Het store-object (bevat book-array en bicycle-object) |
| $.store.bicycle | {"color": "red", "price": 19.95} |
| $.store.bicycle.color | "red" |
| $.store.book | De hele book-array |
| $.store.book[0] | Het eerste book-object |
| $.store.book[0].title | "Sayings of the Century" |
| $.store.book[3].author | "J.R.R. Tolkien" |
Haakjesnotatie
Haakjesnotatie is een alternatief voor puntnotatie dat nuttig is wanneer eigenschapsnamen speciale tekens bevatten, spaties bevatten, of met cijfers beginnen:
$.store['book'][0]['title']
$['store']['bicycle']['color']Haakjesnotatie en puntnotatie zijn uitwisselbaar voor objecteigenschappen. Haakjesnotatie is echter vereist wanneer de eigenschapsnaam dynamisch is of tekens bevat die niet geldig zijn in puntnotatie.
Wildcard-operator
De wildcard-operator * komt overeen met alle elementen in een array of alle eigenschappen in een object. Het is ongelooflijk nuttig voor het extraheren van alle waarden op een bepaald niveau zonder de specifieke sleutels of indices te kennen.
| Expressie | Resultaat |
|---|---|
| $.store.* | Alle waarden in het store-object (book-array en bicycle-object) |
| $.store.book[*] | Alle boeken in de array (alle vier book-objecten) |
| $.store.book[*].author | Alle author-namen: ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"] |
| $.store.*.price | Prijzen van bicycle en de book-array (niet individuele book-prijzen) |
Recursieve afdaling: de dubbele punt-operator
De dubbele punt-operator .. is een van de krachtigste JSONPath-functies. Het zoekt naar de opgegeven sleutel op elk niveau van de JSON-boom, niet alleen de directe children. Zie het als een diepe zoekactie door het hele document.
| Expressie | Resultaat |
|---|---|
| $..author | Alle author-waarden ergens in het document |
| $..price | Alle price-waarden: [8.95, 12.99, 8.99, 22.99, 19.95] |
| $..book[2] | Het derde book, recursief gevonden |
| $..category | Alle category-waarden: ["reference", "fiction", "fiction", "fiction"] |
De recursieve afdalingsoperator is bijzonder nuttig wanneer u het exacte pad naar de benodigde gegevens niet kent, of wanneer dezelfde sleutel op meerdere nestniveaus voorkomt. Als een API-reactie bijvoorbeeld id-velden op verschillende nestniveaus bevat, verzamelt $..id ze allemaal.
Array-slicing
Array-slicing laat u een bereik van elementen uit een array selecteren. De syntaxis [start:end] selecteert elementen van de start-index tot (maar niet inclusief) de eind-index. Zowel positieve als negatieve indices worden ondersteund.
| Expressie | Resultaat |
|---|---|
| $.store.book[0:2] | Eerste twee boeken (indices 0 en 1) |
| $.store.book[1:3] | Tweede en derde boeken (indices 1 en 2) |
| $.store.book[-1] | Laatste book (The Lord of the Rings) |
| $.store.book[-2:] | Laatste twee boeken |
| $.store.book[:2] | Eerste twee boeken (zelfde als [0:2]) |
| $.store.book[2:] | Derde book en verder |
Merk op dat slice-gedrag enigszins kan variëren tussen JSONPath-implementaties. De bovenstaande syntaxis volgt de conventies die door de meeste populaire bibliotheken en de IETF RFC 9535-standaard worden gebruikt.
Filterexpressies
Filterexpressies zijn waar JSONPath echt krachtig wordt. Ze laten u elementen selecteren op basis van voorwaarden in plaats van posities. De filtersyntaxis gebruikt [?(condition)] , waarbij de voorwaarde voor elk element wordt geëvalueerd.
Vergelijkingsoperatoren
JSONPath ondersteunt de volgende vergelijkingsoperatoren in filterexpressies:
| Operator | Betekenis | Voorbeeld |
|---|---|---|
| == | Gelijk aan | [?(@.category == "fiction")] |
| != | Niet gelijk aan | [?(@.category != "fiction")] |
| < | Minder dan | < 10)] |
| <= | Minder dan of gelijk aan | <= 8.99)] |
| > | Groter dan | [?(@.price > 15)] |
| >= | Groter dan of gelijk aan | [?(@.price >= 12.99)] |
| =~ | Regex-match (sommige implementaties) | [?(@.author =~ /Tolkien/i)] |
Praktische filtervoorbeelden
Met behulp van ons voorbeelddocument, hier zijn praktische filterexpressies en hun resultaten:
Find all books cheaper than $10:
< 10)]Retourneert de boeken "Sayings of the Century" ($8.95) en "Moby Dick" ($8.99).
Find all fiction books:
$.store.book[?(@.category == "fiction")]Retourneert drie boeken: "Sword of Honour", "Moby Dick" en "The Lord of the Rings".
Find books with an ISBN:
$.store.book[?(@.isbn)]Retourneert boeken die een isbn-eigenschap hebben: "Moby Dick" en "The Lord of the Rings". Dit werkt omdat het filter controleert op het bestaan van de eigenschap.
Find the most expensive book:
$.store.book[?(@.price > 20)]Retourneert "The Lord of the Rings" ($22.99).
Logische operatoren in filters
U kunt voorwaarden combineren met logische operatoren:
< 10 && @.category == "fiction")]
$.store.book[?(@.price > 15 || @.category == "reference")]De eerste expressie vindt fictieboeken onder $10 (alleen "Moby Dick"). De tweede vindt boeken die ofwel boven $15 zijn of in de referentiecategorie vallen (retourneert "Sayings of the Century" en "The Lord of the Rings").
JSONPath versus XPath
JSONPath was expliciet gemodelleerd naar XPath, en de twee talen delen veel conceptuele overeenkomsten. Het begrijpen van de relatie helpt als u bekend bent met XML-verwerking.
| Functie | JSONPath | XPath |
|---|---|---|
| Root-symbool | $ | / |
| Child-toegang | .key or ['key'] | /element |
| Array-index | [0] | [1] (1-gebaseerd) |
| Wildcard | * | * |
| Recursieve afdaling | .. | // |
| Filter | [?(condition)] | [condition] |
| Attributen | Niet van toepassing (JSON heeft geen attributen) | @attr |
| Huidige node | @ (in filters) | . or current() |
| Parent | Niet ondersteund | .. |
| Assen | Niet ondersteund | 13 assen (ancestor, following, enz.) |
| Gegevensmodel | Objecten en arrays | Elementen, attributen, tekstnodes |
Het belangrijkste verschil is dat XPath opereert op een rijk boommodel met elementen, attributen, tekstnodes, namespaces en verwerkingsinstructies. JSONPath opereert op een eenvoudiger model van objecten (sleutel-waarde-maps) en arrays (geordende lijsten). Deze eenvoud maakt JSONPath makkelijker te leren maar minder expressief dan XPath voor complexe query's.
JSONPath in de praktijk
API-testing
JSONPath is onmisbaar voor API-testing. Wanneer u een aanvraag naar een API stuurt en een grote JSON-reactie ontvangt, laat JSONPath u specifieke waarden beweren zonder de hele structuur handmatig te navigeren. De meeste API-testhulpmiddelen ondersteunen JSONPath van nature.
U kunt bijvoorbeeld in een test verifiëren dat de prijs van het eerste boek minder dan $10 is:
// 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"]Gegevenstransformatie
Bij het integreren van systemen die verschillende gegevensformaten gebruiken, helpt JSONPath specifieke velden te extraheren en transformeren. U kunt waarden uit de ene JSON-structuur halen en ze naar de andere mappen zonder complexe doorloopcode te schrijven.
Configuratiebeheer
Complexe configuratiebestanden bevatten vaak diep geneste JSON. JSONPath laat u specifieke configuratiewaarden opvragen zonder de hele structuur te laden en parsen. Hulpmiddelen zoals jq gebruiken JSONPath-achtige syntaxis voor het verwerken van JSON in command-line-pipelines.
Monitoring en alerting
In observeerbaarheidssystemen kunnen JSONPath-query's metrieken extraheren uit JSON-geformatteerde logs en API-reacties. U kunt alerts instellen die triggeren wanneer een JSONPath-query waarden retourneert die drempels overschrijden.
JSONPath-implementaties
JSONPath is beschikbaar in vrijwel elke programmeertaal. Hier zijn de meest populaire bibliotheken:
| Taal | Bibliotheek | Installatie |
|---|---|---|
| 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-voorbeeld
< 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. - Nul-gebaseerde versus één-gebaseerde indexering: JSONPath gebruikt nul-gebaseerde indexering (het eerste element is [0]), terwijl XPath één-gebaseerde indexering gebruikt (het eerste element is [1]). Dit is een veelvoorkomende bron van off-by-one-fouten.
- Implementatieverschillen: Vóór de IETF-standaard (RFC 9535) varieerden JSONPath-implementaties in hun afhandeling van edge-cases zoals lege resultaten, null-waarden en filtersyntaxis. Test uw expressies altijd met de specifieke bibliotheek die u gebruikt.
Veelvoorkomende valkuilen en tips
In 2024 publiceerde de IETF RFC 9535, die JSONPath formeel standaardiseert. Deze specificatie lost veel van de ambiguïteiten en inconsistenties op die tussen implementaties bestonden. Belangrijke aspecten van de standaard zijn:
- < 10)] ) kan traag zijn op grote documenten omdat het de hele boom moet doorlopen. Gebruik voor prestatiekritische applicaties waar mogelijk specifiekere paden.
- Hoofdlettergevoeligheid: JSONPath is hoofdlettergevoelig. $.Store komt niet overeen met $.store . Dit is consistent met de hoofdlettergevoelige aard van JSON.
- Speciale tekens escapen: Als een sleutelnaam punten of haakjes bevat, moet u haakjesnotatie met aanhalingstekens gebruiken: $['key.with.dots'] in plaats van $.key.with.dots .
- Geen parent-traversal: In tegenstelling tot XPath kan JSONPath niet naar parent-nodes navigeren. Er is geen equivalent voor XPath's .. (parent-axis). JSONPath's .. betekent recursieve afdaling, niet parent.
Als u een nieuw project start, geef dan de voorkeur aan bibliotheken die RFC 9535 implementeren voor maximale compatibiliteit en voorspelbaar gedrag.
JSON-gegevens snel moeten doorzoeken? Probeer onze gratis online JSONPath-tester om expressies in real-time tegen uw JSON-documenten te evalueren.
Probeer JSONPath FinderDe IETF-standaard: RFC 9535
Python-voorbeeld
JSONPath is een querytaal voor JSON, vergelijkbaar met XPath voor XML. Het gebruikt pad-expressies om door JSON-documenten te navigeren en specifieke waarden te extraheren. JSONPath-expressies zoals $.store.book[0].title laten u exacte gegevens binnen complexe geneste JSON-structuren pinpointen zonder aangepaste parse-code te schrijven.
Wat is JSONPath?
JSONPath is ontworpen voor JSON's object- en array-structuur, terwijl XPath is ontworpen voor XML's boom van elementen en attributen. JSONPath gebruikt $ als root, puntnotatie voor objecttoegang en haakjesnotatie voor arrays. XPath gebruikt / voor padscheiding en @ voor attributen. JSONPath is eenvoudiger maar minder functie-rijk dan XPath.
Hoe verschilt JSONPath van XPath?
De dubbele punt (..) in JSONPath is de recursieve afdalingsoperator. Het zoekt naar de benoemde sleutel op alle niveaus van de JSON-structuur, niet alleen de directe children. $..author vindt bijvoorbeeld alle author-sleutels ergens in het hele document, ongeacht hoe diep ze genest zijn.
Wat betekent de dubbele punt (..) in JSONPath?
<, ><=, >< 10)] vindt bijvoorbeeld alle boeken goedkoper dan $10.
Kan JSONPath gegevens filteren op basis van voorwaarden?
JSONPath werd oorspronkelijk in 2007 voorgesteld door Stefan Goessner zonder formele specificatie, wat leidde tot variaties tussen implementaties. In 2024 publiceerde IETF RFC 9535 die JSONPath formeel standaardiseert. Moderne implementaties convergeren naar deze standaard, maar sommige oudere bibliotheken kunnen nog steeds kleine syntaxisverschillen hebben.