繁体   English   中英

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

[英]Is there a JSON equivalent of XQuery/XPath?

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

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

是否有某种查询语言可以用来in [0].objects where 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(', ', @)

您可以在文档中使用更多现场示例。

JS 库被缩小了 19kb,所以可能比一些大,但考虑到广泛的功能,你可能会发现它是值得的。

其他选项

还有一些其他选项可用于遍历/过滤 JSON 数据,并提供一些语法示例来帮助比较...

  • JS路径
    .automobiles{.maker === "Honda" && .year > 2009}.model

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

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

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

从 Dojo 文档:

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

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

我知道的其他选择是

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

哈。

尝试使用JSPath

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

JSON 的 JSPath 就像 XML 的 XPath。

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

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

JQ定义为J SON q uery语言非常类似于JSONPath -见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常见问题有指向教程等的指针。

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

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

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

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

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]

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

最新的 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 和 XPath 函数和运算符 3.1] 中的新函数来支持它们。

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

这是在 xml 的类似 xpath 行上的一个非常简单的实现。 它的名称为 jpath。

我知道 OP 用javascript标记了这个问题,但在我的情况下,我正在寻找完全相同的东西,但是来自 Java 后端(使用 Camel)。

如果您使用像 Camel 这样的集成框架, jsonPath有趣的事情也很有用,自 Camel 2.13 以来,特定的Camel 组件也支持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")

使用起来非常简单。

jsonata https://jsonata.org/

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM