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

当在复杂的JSON数组和散列中搜索项时,比如:

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

是否有某种查询语言,我可以用来找到一个项目in [0].objects where id = 3?

136413 次浏览

是的,它叫做JSONPath:

它也被集成到DOJO中。

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

来自Dojo文档:

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

JSONselect对这个问题有另一种观点(类似CSS选择器,而不是XPath),并且有JavaScript实现

XQuery可用于查询JSON,前提是处理器提供JSON支持。这是一个简单的例子,如何使用BaseX来查找“id”= 1的对象:

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

我知道的其他选择是

  1. JSONiq规范,该规范指定了两种子类型的语言:一种隐藏XML细节并提供类似js的语法,另一种使用JSON构造函数等丰富XQuery语法。Zorba实现JSONiq。
  2. 电晕构建在MarkLogic之上,提供了一个用于存储、管理和搜索XML、JSON、文本和二进制内容的REST接口。
  3. MarkLogic 6和以后提供类似Corona开箱即用的REST接口。
  4. MarkLogic 8及以后版本在它们的XQuery和服务器端JavaScript环境中原生支持JSON。可以在上面应用XPath。

HTH。

尝试使用JSPath

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

JSON的JSPath就像XML的XPath。

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

Json指针似乎也得到了越来越多的支持。

JMESPath是一个非常成熟的库,具有详细的规范和对多种语言的支持。

语法的例子:
// 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(', ', @)

的文档中还有很多你可以使用的实例。

JS库精简了19kb,因此可能比某些库大,但考虑到广泛的特性,您可能会发现它值得。

其他选项

还有一些用于遍历/过滤JSON数据的其他选项,以及一些语法示例,以帮助您进行比较…

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

  • json: select ()(更多的灵感来自CSS选择器)
    .automobiles .maker:val("Honda") .model

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

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

商店里所有的鞋子都是红色的,价格在50美元以下

美元. .鞋子。*[颜色为红色,价格<50)

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

您可以创建自定义模式和映射,从而完全控制XPath引擎如何处理数据。模式是一种定义如何在数据中定义元素、子元素、属性和节点值的方法。然后你可以创建自己的表达式来适应。

假设你有一个名为data的变量,其中包含来自问题的JSON,你可以使用jsel写:

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

这将返回任何id属性为3的节点。属性是对象内的任何基本元素(字符串、数字、日期、正则表达式)值。

@Naftule -使用" defy .js",可以用XPath表达式查询JSON结构。看看这个计算器,了解它是如何工作的:

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

与JSONPath不同,“defy .js”提供了对查询语法的全面支持——对JSON结构上的XPath。

defy .js的源代码可以在这里找到:
https://github.com/hbi99/defiant.js < / p >

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

如果你像我一样,只想做基于路径的查找,但不关心真正的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'

试试这个——https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

这是一个非常简单的实现,类似于xpath for xml。它的名称是jpath。

是否存在某种查询语言…

金桥定义了一个JSON uery语言,它非常类似于JSONPath——参见https://github.com/stedolan/jq/wiki/For-JSONPath-users

... 我可以用它在[0]中找到一个项目。id = 3的对象?

我假设这意味着:找到id == 3指定键下的所有JSON对象,无论对象可能在哪里。对应的jq查询是:

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

其中“|”是管道操作符(如在命令shell管道中),而段“..| objects”对应于“无论对象可能在哪里”。

jq的基本原理在很大程度上是显而易见或直观的,或者至少相当简单,如果您熟悉命令-shell管道,那么其余的大部分内容都很容易掌握。jq 常见问题解答有指向教程等的指针。

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

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

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

JMESPath现在似乎很流行(截至2020年),并解决了JSONPath的一些问题。它适用于许多语言。

为了增加更多的选择,还有XPath。XPath 3.1处理JSON和XML。在XPath 3.1中,您需要的查询是?0?Objects?*[?id=3]

我知道OP用javascript标记了问题,但在我的情况下,我看起来完全一样,但从Java后端(与Camel)。

有趣的是,如果你正在使用像Camel这样的集成框架,它也会很有用,自Camel 2.13以来,特定的骆驼组件也支持jsonPath

例子来自上面的Camel文档:

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")

使用起来很简单。

最新的XPath规范包含JSON支持:

XPath的主要目的是处理XML树和JSON树的节点。XPath得名于它使用路径符号在XML文档的层次结构中导航。XPath使用紧凑的非XML语法,以方便在uri和XML属性值中使用XPath。XPath 3.1为导航JSON树添加了类似的语法。

这也是XQuery的情况:

JSON是一种轻量级的数据交换格式,广泛用于在web上交换数据和在数据库中存储数据。许多应用程序将JSON与XML和HTML一起使用。XQuery 3.1扩展了XQuery以支持JSON和XML,向数据模型添加了映射和数组,并使用语言中的新表达式和[XQuery and XPath functions and Operators 3.1]中的新函数来支持它们。

jsonata https://jsonata.org/

它有一个操场,你可以下载图书馆