是否有与XQuery / XPath等效的JSON?


221

搜索复杂的JSON数组和哈希中的项目时,例如:

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

我可以使用某种查询语言来查找商品in [0].objects where id = 3吗?


除非你做一个。将查询留给服务器,然后使用REST仅获取所需的数据。
zzzzBov 2011年

5
+1好主意。明天要写这个…

2
不是XPath,但我发现JLinq非常好(使代码看起来像in(...).where(...).select(...)):hugoware.net/Projects/jLinq
pimvdb 2011年

4
这很令人沮丧,因为那里有很多库,但是没有一个库能达到公认的标准。我们有一个供第三方使用的库,因此我们需要提供一种广为人知和使用的查询语言。
David Thielen 2012年

1
当然,你可以使用jsel - github.com/dragonworx/jsel -给你有一个变量data,其中包含您的JSON对象,你可以这样写:jsel(data).select("//*[@id=3]")它会用3.返回包含ID键的对象
阿里

Answers:


122

是的,它称为JSONPath。源现在在GitHub上

它还集成到DOJO中


3
Brian的答案建议应使用jsonQuery模块而不是 dojo中的jsonPath模块。
hugomg 2011年

5
这有多牢固?而且我找不到对我们而言是交易杀手的Java或C#版本。
大卫·蒂伦

2
此处链接的站点提供Javascript和PHP。如果您需要Java实现,可以在这里找到:code.google.com/p/json-path
Matthias Ronge 2012年

2
我应该提到JSONPath并非基于XPath形式语义。JSONiq可能是一个更好的选择。
wcandillon

1
@Paramaeleon效果很好。顺便说一下,该项目已迁移到GitHub。迈克可能希望将其添加到答案中,因为人们不断对此发表评论。
富兰克林于

21

我认为JSONQuery是JSONPath的超集,因此在dojo中将其替换。然后还有RQL

从Dojo文档中:

JSONQuery是JSONPath的扩展版本,具有安全性,易用性以及一系列全面的数据查询工具,包括过滤,递归搜索,排序,映射,范围选择以及具有通配符字符串比较和各种运算符的灵活表达式的附加功能。

JSONselect在问题上有另一种观点(类似于CSS选择器,而不是XPath),并且具有JavaScript实现


4
github JSONQuery链接似乎已死。JSONSelect现在也具有JavaScript版本。
Henrik AastedSørensen'12

19

我知道的其他替代方法是

  1. JSONiq规范,该规范指定两种语言的子类型:一种隐藏XML详细信息并提供类似JS的语法,另一种使用JSON构造函数等丰富XQuery语法。Zorba实现JSONiq。
  2. 电晕,这建立在MarkLogic的顶部提供了一个REST接口,用于存储,管理和检索XML,JSON,文本和二进制内容。
  3. MarkLogic 6及更高版本提供了与Corona类似的REST接口。
  4. MarkLogic 8和更高版本在其XQuery和服务器端JavaScript环境中都原生支持JSON。您可以在其上应用XPath。

HTH。


3
现在有一个JSONiq实现:Zorba 2.6正式支持它。
Ghislain Fourny

注意:MarkLogic从版本8开始本地存储JSON,并允许直接在其上应用XPath。
grtjn

18

总结一些当前的遍历/过滤JSON数据的选项,并提供一些语法示例...

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

  • json:select()(更多受CSS选择器启发)
    .automobiles .maker:val("Honda") .model

  • JSONPath(更多受XPath启发)
    $.automobiles[?(@.maker='Honda')].model

我认为JSPath看起来最好,因此我将尝试将其与AngularJS + CakePHP应用程序集成。

(我最初将此答案发布在另一个线程中,但也认为在这里也很有用。)


很棒的摘要和示例,也因为提到了CSS选择器或XPath中的启发。
Jochem Schulenklopper

13

尝试使用JSPath

JSPath是一种特定于域的语言(DSL),使您可以导航和查找JSON文档中的数据。使用JSPath,您可以选择JSON项以检索它们包含的数据。

JSON的JSPath就像XML的XPath一样。

它已针对Node.js和现代浏览器进行了大幅优化。


9

如果处理器提供JSON支持,则可以使用XQuery查询JSON。这是一个简单的示例,说明如何使用BaseX查找“ id” = 1的对象:

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

(已有6年了)Saxon将运行XQuery 3.1,该查询将查询JSON。我的Saxon经验是使用Java运行的jar文件。有一个名为saxon-java的节点模块,但是我不确定w / json如何工作。萨克森尼(Saxonica)还有另一种新东西,叫做Saxon-JS。
查尔斯·罗斯(Charles Ross)'18

9

是否有某种查询语言...

jq定义了一种与JSONPath非常相似的J SON q语言-请参阅https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [哪个]我可以用来在[0] .ids = 3的对象中找到一个项目?

我将假设这意味着:无论对象位于何处,在id == 3的指定键下查找所有JSON对象。相应的jq查询为:

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

其中“ |” 是管道运算符(如在命令外壳管道中一样),并且段“ .. | object”对应于“无论对象可能在哪里”。

jq的基础知识在很大程度上是显而易见的,直观的,或者至少是相当简单的,如果您完全熟悉命令外壳程序管道,那么其余大多数就很容易理解。jq FAQ具有指向教程等的指针。

jq也类似于SQL,因为它支持CRUD操作,尽管jq处理器从不覆盖其输入。jq还可以处理JSON实体流。

在评估面向JSON的查询语言时,您可能希望考虑的另外两个标准是:

  • 它支持正则表达式吗?(jq 1.5全面支持PCRE regex)
  • 图灵完成了吗?(是的)

8

Defiant.js看起来也很酷,这是一个简单的示例:

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

不幸的是,目前尚未在npm上发布,需要手动安装...
Andrew Mao


7

Jsel很棒,它基于真正的XPath引擎。它允许您创建XPath表达式以查找任何类型的JavaScript数据,而不仅仅是对象(字符串)。

您可以创建自定义架构和映射,以完全控制XPath引擎如何遍历数据。模式是一种定义如何在数据中定义元素,子级,属性和节点值的方法。然后,您可以创建适合自己的表达式。

假定您有一个名为的变量data,其中包含问题中的JSON,则可以使用jsel编写:

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

这将返回任何id属性为3的节点。属性是对象中任何原始值(字符串,数字,日期,正则表达式)。


6

ObjectPath是一种类似于XPath或JSONPath的查询语言,但是由于嵌入式算术计算,比较机制和内置函数,其功能更加强大。请参见语法:

在商店中找到所有红色的鞋子,且价格低于50

$ .. shoes。* [颜色为“红色”,价格<50]


我喜欢网站上的第一个示例,并且ObjectPath可以在类似于shell的interactve模式下运行非常棒,但是我要寻找的是在Python脚本中使用ObjectPath。您能否指出一个显示如何将ObjectPath用作库的示例?我在网站上找不到类似的内容。
piokuc 2014年

请参阅github上有关Python使用的部分。我们会将其添加到网站-目前确实很难找到。如果您需要其他帮助,可以在google group上发布问题。
Ela Bednarek

谢谢Ela,github页面上添加的示例正是所需要的。
piokuc 2014年


3

如今(截至2020年),JMESPath似乎非常流行,并解决了JSONPath的许多问题。它适用于多种语言。


1

如果您像我一样,并且只想进行基于路径的查找,但不关心真正的XPath,则lodash _.get()可以使用。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'

不幸的是,该函数只能返回一个结果,它不支持获取匹配项的数组,这是其他库的亮点。
西蒙东

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.