在复杂的 JSON 数组和哈希中搜索项目时,例如:
[
{ "id": 1, "name": "One", "objects": [
{ "id": 1, "name": "Response 1", "objects": [
// etc.
}]
}
]
是否有某种查询语言可用于查找项目 in [0].objects where id = 3
?
in(...).where(...).select(...)
):hugoware.net/Projects/jLinq。
data
,您可以编写:jsel(data).select("//*[@id=3]")
,它会返回包含 id 键为 3 的对象。
是的,它被称为 JSONPath:
它也集成到 DOJO 中。
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(', ', @)
您可以在 the docs 中使用更多实时示例。
JS 库缩小了 19kb,因此可能比某些库大,但考虑到广泛的功能,您可能会觉得值得。
其他选项
还有一些用于遍历/过滤 JSON 数据的其他选项,以及一些语法示例来帮助您比较...
JSPath .automobiles{.maker === "本田" && .year > 2009}.model
json:select() (更多灵感来自 CSS 选择器) .automobiles .maker:val("Honda") .model
JSONPath(更多灵感来自 XPath)$.automobiles[?(@.maker='Honda')].model
我认为 JSONQuery 是 JSONPath 的超集,因此是 replaces it in dojo。然后还有RQL。
来自 Dojo 文档:
JSONQuery 是 JSONPath 的扩展版本,具有额外的安全性、易用性和一整套数据查询工具,包括过滤、递归搜索、排序、映射、范围选择以及具有通配符字符串比较和各种运算符的灵活表达式。
JSONselect 对问题有另一种观点(类似于 CSS 选择器,而不是 XPath)并有一个 JavaScript implementation。
我知道的其他选择是
JSONiq 规范,它指定了两种语言子类型:一种隐藏 XML 细节并提供类似 JS 的语法,另一种使用 JSON 构造函数等丰富 XQuery 语法。 Zorba 实现 JSONiq。 Corona 建立在 MarkLogic 之上,提供了一个 REST 接口,用于存储、管理和搜索 XML、JSON、文本和二进制内容。 MarkLogic 6 及更高版本提供了与 Corona 类似的开箱即用的 REST 接口。 MarkLogic 8 及更高版本在其 XQuery 和服务器端 JavaScript 环境中都原生支持 JSON。您可以在其上应用 XPath。
HTH。
尝试使用 JSPath
JSPath 是一种特定于域的语言 (DSL),它使您能够在 JSON 文档中导航和查找数据。使用 JSPath,您可以选择 JSON 项目以检索它们包含的数据。
JSON 的 JSPath 类似于 XML 的 XPath。
它针对 Node.js 和现代浏览器进行了大量优化。
是否有某种查询语言...
jq 定义了一种与 JSONPath 非常相似的 JSON query 语言 -- 请参阅 https://github.com/stedolan/jq/wiki/For-JSONPath-users
... [which] 我可以用来在 [0].objects 中找到 id = 3 的项目?
我假设这意味着:在 id == 3 的指定键下找到所有 JSON 对象,无论对象在哪里。相应的 jq 查询将是:
.[0].objects | .. | objects | select(.id==3)
其中“|”是管道运算符(如在命令外壳管道中),并且段“.. | objects”对应于“无论对象可能在哪里”。
jq 的基础知识在很大程度上是显而易见的或直观的,或者至少非常简单,如果您完全熟悉命令外壳管道,那么其余的大部分内容都很容易掌握。 jq FAQ 有指向教程等的指针。
jq 也与 SQL 类似,因为它支持 CRUD 操作,尽管 jq 处理器从不覆盖其输入。 jq 还可以处理 JSON 实体流。
在评估面向 JSON 的查询语言时,您可能希望考虑的另外两个标准是:
它支持正则表达式吗? (jq 1.5 全面支持 PCRE 正则表达式)
它是图灵完备的吗? (是的)
XQuery 可用于查询 JSON,前提是处理器提供 JSON 支持。这是一个简单的示例,如何使用 BaseX 查找 "id" = 1 的对象:
json:parse('[
{ "id": 1, "name": "One", "objects": [
{ "id": 1, "name": "Response 1", "objects": [ "etc." ] }
]}
]')//value[.//id = 1]
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
Jsel 很棒,它基于真正的 XPath 引擎。它允许您创建 XPath 表达式来查找任何类型的 JavaScript 数据,而不仅仅是对象(也包括字符串)。
您可以创建自定义模式和映射,以完全控制 XPath 引擎可遍历数据的方式。模式是一种定义如何在数据中定义元素、子项、属性和节点值的方式。然后,您可以创建适合自己的表达式。
假设您有一个名为 data
的变量,其中包含问题中的 JSON,您可以使用 jsel 编写:
jsel(data).select("//*[@id=3]")
这将返回 id
属性为 3 的任何节点。属性是对象内的任何原始(字符串、数字、日期、正则表达式)值。
ObjectPath 是一种类似于 XPath 或 JSONPath 的查询语言,但由于嵌入式算术计算、比较机制和内置函数而更加强大。见语法:
在商店中找到所有红色且价格低于 50 的鞋子
$..shoes.*[颜色为“红色”且价格 < 50]
JMESPath 如今(截至 2020 年)似乎很受欢迎,并解决了 JSONPath 的许多问题。它适用于多种语言。
@Naftule - 使用“defiant.js”,可以使用 XPath 表达式查询 JSON 结构。查看此评估器以了解其工作原理:
http://www.defiantjs.com/#xpath_evaluator
与 JSONPath 不同,“defiant.js”提供了对查询语法的全面支持——对 JSON 结构的 XPath。
defiant.js 的源代码可以在这里找到:
https://github.com/hbi99/defiant.js
只是为了增加选择,还有 XPath。 XPath 3.1 处理 JSON 以及 XML。在 XPath 3.1 中,您需要的查询是 ?0?Objects?*[?id=3]
latest XPath spec 包括 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 和 XPath 函数和运算符 3.1] 中的新函数来支持它们。
如果您像我一样只想进行基于路径的查找,而不关心真正的 XPath,那么 lodash 的 _.get()
可以工作。来自 lodash 文档的示例:
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
这是在 xml 的类似 xpath 行上的一个非常简单的实现。它的名称为 jpath。
我知道 OP 用 javascript
标记了这个问题,但就我而言,我看起来完全一样,但来自 Java 后端(使用 Camel)。
如果您使用像 Camel 这样的集成框架,那么有趣的事情也很有用,自 Camel 2.13 起,特定的 Camel Component 也支持 jsonPath
。
来自上述骆驼文档的示例:
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")
使用起来非常简单。