【问题标题】:Is there a JSON equivalent of XQuery/XPath?是否有与 XQuery/XPath 等效的 JSON?
【发布时间】:2012-01-18 20:44:06
【问题描述】:

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

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

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

【问题讨论】:

  • 除非你做一个。将查询留给服务器,并使用 REST 仅获取您需要的数据。
  • +1 好主意。明天写这个……
  • 不是 XPath,但我发现 JLinq 非常好(这使得代码读起来像 in(...).where(...).select(...)):hugoware.net/Projects/jLinq
  • 这很令人沮丧,因为那里有很多库,但没有一个能达到普遍接受的标准。我们有一个第三方使用的库,因此我们需要提供一种广为人知和使用的查询语言。
  • 当然,你可以使用 jsel - github.com/dragonworx/jsel - 假设你有一个变量 data 包含你的 JSON 对象,你可以写:jsel(data).select("//*[@id=3]") 它会返回包含 id 键的对象3.

标签: javascript json xpath xquery


【解决方案1】:

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 === "Honda" && .year > 2009}.model

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

  • JSONPath(更多灵感来自 XPath)
    $.automobiles[?(@.maker='Honda')].model

【讨论】:

  • 很棒的总结和例子,也是因为提到了在 CSS 选择器或 XPath 中找到的灵感。
【解决方案2】:

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] 中的新函数来支持它们。

【讨论】:

    【解决方案3】:

    是的,它叫JSONPath

    它也被集成到DOJO

    【讨论】:

    • Brian 的回答建议 jsonQuery 模块应该使用 dojo 中 jsonPath 模块的instead
    • 这有多坚固?而且我找不到对我们来说是一个交易杀手的 Java 或 C# 版本。
    • 此处链接的站点提供 Javascript 和 PHP。如果您需要 Java 实现,这里有一个:code.google.com/p/json-path
    • 我应该提到 JSONPath 不是基于 XPath 形式语义的。 JSONiq 可能是更好的选择。
    • @Paramaeleon 效果很好。顺便说一下,该项目是migrated to GitHub。迈克可能想将此添加到答案中,因为人们一直对此发表评论。
    【解决方案4】:

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

    如果您使用像 Camel 这样的集成框架,这也是一件有趣的事情,jsonPath 自 Camel 2.13 起也被特定的 Camel Component 支持。

    来自上述 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")
    

    使用起来非常简单。

    【讨论】:

      【解决方案5】:

      除了选择之外,还有 XPath。 XPath 3.1 处理 JSON 以及 XML。在 XPath 3.1 中,您需要的查询是 ?0?Objects?*[?id=3]

      【讨论】:

        【解决方案6】:

        我认为 JSONQuery 是 JSONPath 的超集,因此是 replaces it in dojo。然后还有RQL

        来自 Dojo 文档:

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

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

        【讨论】:

        • github JSONQuery 链接似乎已失效。 JSONSelect 现在也有 JavaScript 版本了。
        【解决方案7】:

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

        【讨论】:

        • 是的,它看起来非常清晰和干净,语法非常接近标准 JavaScript,并且跨多种语言标准化。 ?
        【解决方案8】:

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

        jq 定义了一种与 JSONPath 非常相似的 JSON query 语言 -- 参见 https://github.com/stedolan/jq/wiki/For-JSONPath-users

        ... [which] 我可以用来在 [0].objects where 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 正则表达式)
        • 它是图灵完备的吗? (是的)

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

          【解决方案10】:

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

          【讨论】:

          • 不幸的是,该函数只能返回一个结果,它不支持获取匹配项的数组,这是其他库的亮点。
          【解决方案11】:

          我知道的其他选择是

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

          HTH。

          【讨论】:

          • 现在有一个 JSONiq 实现:Zorba 2.6 正式支持它。
          • 注意:MarkLogic 从版本 8 开始本地存储 JSON,并允许直接在其上应用 XPath。
          【解决方案12】:

          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 上发布,需要手动安装...
          【解决方案13】:

          @Naftule - 使用“defiant.js”,可以使用 XPath 表达式查询 JSON 结构。查看此评估器以了解其工作原理:

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

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

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

          【讨论】:

            【解决方案14】:

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

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

            $..shoes.*[颜色为“红色”且价格

            【讨论】:

            • 我喜欢网站上的第一个示例,ObjectPath 可以在交互的、类似 shell 的模式下运行非常棒,但我正在寻找的是在 Python 脚本中使用 ObjectPath。你能给我举个例子来展示如何使用 ObjectPath 作为库吗?我在网站上找不到类似的东西。
            • 请参阅github 上有关 Python 使用的部分。我们将把它添加到网站上——目前确实很难找到。如果您需要任何进一步的帮助,可以在google group 上发布问题。
            • 谢谢Ela,github页面上添加的例子正是需要的。
            【解决方案15】:

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

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

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

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

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

            【讨论】:

              【解决方案16】:

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

              【讨论】:

                【解决方案17】:

                尝试使用JSPath

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

                用于 JSON 的 JSPath 类似于用于 XML 的 XPath。

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

                【讨论】:

                  【解决方案18】:

                  XQuery 可用于查询 JSON,前提是处理器提供 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。我的撒克逊经验是使用 java 运行的 jar 文件。有一个名为 saxon-java 的节点模块,但我不确定 w/json 是如何工作的。 Saxonica 还有一个新的东西叫做 Saxon-JS。
                  猜你喜欢
                  • 1970-01-01
                  • 2018-04-30
                  • 1970-01-01
                  • 2014-12-19
                  • 2021-04-30
                  • 2010-09-08
                  • 2013-02-04
                  • 2017-01-01
                  • 2012-11-21
                  相关资源
                  最近更新 更多