Is there a JSON equivalent of XQuery/XPath? [closed]
Asked Answered
H

19

252

When searching for items in complex JSON arrays and hashes, like:

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

Is there some kind of query language I can used to find an item in [0].objects where id = 3?

Hassan answered 12/12, 2011 at 21:50 Comment(11)
not unless you make one. Leave the querying to the server, and use REST to get only the data you need.Meares
+1 good idea. Gonna write this tomorrow…Triple
Not XPath, but I've found JLinq pretty good (which makes code to read like in(...).where(...).select(...)): hugoware.net/Projects/jLinq.Ptisan
This is frustrating because there's lots of libraries out there, but nothing approaching a commonly accepted standard. We have a library used by 3rd parties so we need to provide a query language that is widely known and used.Pantheon
Some other options are suggested here: #777955Apivorous
Sure, you can use jsel - github.com/dragonworx/jsel - given you have a variable data which contains your JSON object, you would write: jsel(data).select("//*[@id=3]") and it would return the object containing the id key with 3.Preselector
Everything here seems pretty out of date. The most recent and maintained solution I found is github.com/dfilatov/jspath.Swerve
tools.ietf.org/html/rfc6901 offers a simple pointer to a specific location. It's not a query syntax, but perhaps it's at least a place for some common approach?Acidic
npmjs.com/package/jsonpath#jpqueryobj-pathexpression-countPizzeria
I have made tiny script which can be used for some common purposes extract/delete/set variable in JSON object: github.com/burlachenkok/json_processingSicken
Couchbase developed N1QL which is meant to query JSON data and return JSON data.Sterne
G
137

Yup, it's called JSONPath:

It's also integrated into DOJO.

Gallion answered 12/12, 2011 at 21:55 Comment(10)
Brian's answer suggests that the jsonQuery module should be used instead of the jsonPath module in dojo.Marinmarina
How solid is this? And I can't find a Java or C# version which is a deal killer for us.Pantheon
The site linked here provides for Javascript and PHP. If you need a Java implementation, there’s one here: code.google.com/p/json-pathTrilly
I should mention that JSONPath is not based on the XPath formal semantic. JSONiq might be a better option.Aerophyte
I would use jsel - github.com/dragonworx/jsel - it uses a real XPath engine and is highly customizable. Does everything JSONPath does plus more.Preselector
jsel is for JS not PHPGoldengoldenberg
@Paramaeleon That works great. The project has been migrated to GitHub, by the way. Mike may want to add this to the answer, since people keep commenting about this.Perretta
Regarding C# version, as of 2020 it is supported in Newtonsoft.Json and there is an open issue to support it in System.Text.Json github.com/dotnet/runtime/issues/31068Hankering
I'm very confused. The question is tagged Javascript but the Github link is for a Java library. Wut???Goodill
Yea, looks like the Github link was to the wrong thing. There's a Javascript version of JSONPath which is linked above. I reverted back to the previous edit.Gallion
A
29

JMESPath is quite a mature library with a detailed specification and support for multiple languages.

Syntax Examples:
// Select a single item
people[1].firstName

// Select a slice of an array
people[0:5]

// Select all the first names
people[*].firstName

// Select all first names based on search term
people[?state=='VA'].firstName

// Count how many people are over 35
length(people[?age>`35`])

// Select only the name and age of people over 35
people[?age>`35`].{name: name, age: age}

// Join expressions together to sort and join elements into a string
people[?state == 'WA'].name | sort(@) | join(', ', @)

There are plenty more live examples you can play with in the docs.

The JS library is 19kb minified, so possibly larger than some, but considering the extensive features, you might find it worth it.

Other Options

There are also some other options for traversing/filtering JSON data, along with some syntax examples to help you compare...

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

  • json:select() (inspired more by CSS selectors)
    .automobiles .maker:val("Honda") .model

  • JSONPath (inspired more by XPath)
    $.automobiles[?(@.maker='Honda')].model

Apivorous answered 14/6, 2013 at 3:5 Comment(1)
Great summary and examples, also because of mentioning the inspiration found in either CSS selectors or XPath.Sleuthhound
C
24

I think JSONQuery is a superset of JSONPath and thus replaces it in dojo. Then there's also RQL.

From Dojo documentation:

JSONQuery is an extended version of JSONPath with additional features for security, ease of use, and a comprehensive set of data querying tools including filtering, recursive search, sorting, mapping, range selection, and flexible expressions with wildcard string comparisons and various operators.

JSONselect has another point of view on the question (CSS selector-like, rather than XPath) and has a JavaScript implementation.

Ceroplastic answered 12/12, 2011 at 22:22 Comment(1)
The github JSONQuery link seems to be dead. JSONSelect also has a JavaScript version now.Heaves
Z
21

Other alternatives I am aware of are

  1. JSONiq specification, which specifies two subtypes of languages: one that hides XML details and provides JS-like syntax, and one that enriches XQuery syntax with JSON constructors and such. Zorba implements JSONiq.
  2. Corona, which builds on top of MarkLogic provides a REST interface for storing, managing, and searching XML, JSON, Text and Binary content.
  3. MarkLogic 6 and later provide a similar REST interface as Corona out of the box.
  4. MarkLogic 8 and later support JSON natively in both their XQuery and Server-side JavaScript environment. You can apply XPath on it.

HTH.

Zachary answered 13/12, 2011 at 6:36 Comment(2)
There is now a JSONiq implementation: Zorba 2.6 officially supports it.Oswin
Note: MarkLogic stores JSON natively as of version 8, and allows applying XPath on it directly.Zachary
D
16

Try to using JSPath

JSPath is a domain-specific language (DSL) that enables you to navigate and find data within your JSON documents. Using JSPath, you can select items of JSON in order to retrieve the data they contain.

JSPath for JSON like an XPath for XML.

It is heavily optimized both for Node.js and modern browsers.

Detonation answered 14/11, 2012 at 20:23 Comment(0)
S
13

Is there some kind of query language ...

jq defines a JSON query language that is very similar to JSONPath -- see https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [which] I can used to find an item in [0].objects where id = 3?

I'll assume this means: find all JSON objects under the specified key with id == 3, no matter where the object may be. A corresponding jq query would be:

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

where "|" is the pipe-operator (as in command shell pipes), and where the segment ".. | objects" corresponds to "no matter where the object may be".

The basics of jq are largely obvious or intuitive or at least quite simple, and most of the rest is easy to pick up if you're at all familiar with command-shell pipes. The jq FAQ has pointers to tutorials and the like.

jq is also like SQL in that it supports CRUD operations, though the jq processor never overwrites its input. jq can also handle streams of JSON entities.

Two other criteria you might wish to consider in assessing a JSON-oriented query language are:

  • does it support regular expressions? (jq 1.5 has comprehensive support for PCRE regex)
  • is it Turing-complete? (yep)
Sackcloth answered 4/3, 2018 at 4:22 Comment(0)
S
11

XQuery can be used to query JSON, provided that the processor offers JSON support. This is a straightforward example how BaseX can be used to find objects with "id" = 1:

json:parse('[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [ "etc." ] }
    ]}
]')//value[.//id = 1]
Sicyon answered 12/12, 2011 at 22:32 Comment(1)
(6 years on) Saxon will run XQuery 3.1, which queries JSON. My Saxon experience is using the jar file run by java. There is a node module named saxon-java but I am not sure how that works w/json. And there is another new thing from Saxonica called Saxon-JS.Tippet
C
10

Json Pointer seem's to be getting growing support too.

Claus answered 29/1, 2013 at 11:52 Comment(0)
A
9

Defiant.js looks also pretty cool, here's a simple example:

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
Alberich answered 2/7, 2015 at 14:27 Comment(1)
Unfortunately, not published on npm at the moment and requires manual installation...Swerve
P
8

Jsel is awesome and is based on a real XPath engine. It allows you to create XPath expressions to find any type of JavaScript data, not just objects (strings too).

You can create custom schemas and mappings to give you complete control over how your data is walkable by the XPath engine. A schema is a way of defining how elements, children, attributes, and node values are defined in your data. Then you can create your own expressions to suit.

Given you had a variable called data which contained the JSON from the question, you could use jsel to write:

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

This will return any node with an id attribute of 3. An attribute is any primitive (string, number, date, regex) value within an object.

Preselector answered 13/8, 2013 at 5:0 Comment(0)
H
7

ObjectPath is a query language similar to XPath or JSONPath, but much more powerful thanks to embedded arithmetic calculations, comparison mechanisms and built-in functions. See the syntax:

Find in the shop all shoes of red color and price less than 50

$..shoes.*[color is "red" and price < 50]

Herrin answered 10/8, 2013 at 1:17 Comment(3)
I like the first example on the website and it's great that ObjectPath can be run in an interactve, shell-like mode, but what I'm looking for is to use ObjectPath in a Python script. Can you point me to an example showing how to use ObjectPath as a library? I can't find anything like that on the website.Wilkison
Please see the section about Python usage on github. We'll add this to the website - it's indeed hard to find at the moment. If you need any further help, you can post a question on google group.Herrin
Thank you, Ela, the examples added on the github page are exactly what was needed.Wilkison
H
7

The latest XPath spec includes JSON support:

The primary purpose of XPath is to address the nodes of XML trees and JSON trees. XPath gets its name from its use of a path notation for navigating through the hierarchical structure of an XML document. XPath uses a compact, non-XML syntax to facilitate use of XPath within URIs and XML attribute values. XPath 3.1 adds a similar syntax for navigating JSON trees.

This is also the case for XQuery:

JSON is a lightweight data-interchange format that is widely used to exchange data on the web and to store data in databases. Many applications use JSON together with XML and HTML. XQuery 3.1 extends XQuery to support JSON as well as XML, adding maps and arrays to the data model and supporting them with new expressions in the language and new functions in [XQuery and XPath Functions and Operators 3.1].

Henriettehenriha answered 6/3, 2021 at 18:44 Comment(2)
Do you know of any implementations for node?Quamash
This should be upvoted as the correct answer. XPath supports JSON natively.Strobila
H
6

JMESPath seems to be very popular these days (as of 2020) and addresses a number of issues with JSONPath. It's available for many languages.

Hebdomadal answered 8/1, 2020 at 13:54 Comment(1)
Yeah that looks quite clear and clean, with a syntax very close to standard JavaScript AND is standardised across multiple languages. 👍Apivorous
S
5

@Naftule - with "defiant.js", it is possible to query a JSON structure with XPath expressions. Check out this evaluator to get an idea of how it works:

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

Unlike JSONPath, "defiant.js" delivers the full-scale support of the query syntax - of XPath on JSON structures.

The source code of defiant.js can be found here:
https://github.com/hbi99/defiant.js

Smallman answered 2/1, 2014 at 12:58 Comment(0)
H
4

Just to add to the choices, there's also XPath. XPath 3.1 handles JSON as well as XML. In XPath 3.1 your required query is ?0?Objects?*[?id=3]

Hyponitrite answered 31/10, 2020 at 22:21 Comment(0)
R
2

If you're like me and you just want to do path-based lookups, but don't care about real XPath, lodash's _.get() can work. Example from 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'
Reach answered 24/6, 2016 at 19:47 Comment(1)
Unfortunately that function can only return a single result, it doesn't support fetching an array of matching items, which is where the other libraries shine.Apivorous
T
1

Try this out - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

It's a very simple implementation on similar line of xpath for xml. It's names as jpath.

Thaddeusthaddus answered 29/3, 2017 at 17:6 Comment(2)
This question is tagged javascript but this library appears to be for javaPuklich
It has a Javascript version too - github.com/satyapaul/jpath/blob/master/jpath.js Here is he git home page for the project - github.com/satyapaul/jpathThaddeusthaddus
P
1

I know the OP tagged the question with javascript but in my case I was looking exactly the same thing but from a Java backend (with Camel).

An interesting thing that can also be useful if you are using an integration framework like Camel, jsonPath is also supported by a specific Camel Component since Camel 2.13.

Example from the Camel doc above:

from("queue:books.new")
  .choice()
    .when().jsonpath("$.store.book[?(@.price < 10)]")
      .to("jms:queue:book.cheap")
    .when().jsonpath("$.store.book[?(@.price < 30)]")
      .to("jms:queue:book.average")
    .otherwise()
      .to("jms:queue:book.expensive")

which is quite straightforward to use.

Preferable answered 13/11, 2020 at 11:27 Comment(0)
G
1

jsonata https://jsonata.org/

It has a playground and you can download the library

Guarino answered 23/7, 2022 at 20:53 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewAmand

© 2022 - 2024 — McMap. All rights reserved.