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

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

是否有某种查询语言,我可以用来在[0]中找到一个项目。id = 3的对象?


当前回答

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

其他回答

尝试使用JSPath

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

JSON的JSPath就像XML的XPath。

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

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

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

有趣的是,如果您使用的是像Camel这样的集成框架,jsonPath也由特定的Camel组件支持,从Camel 2.13开始。

例子来自上面的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")

使用起来很简单。

是否存在某种查询语言…

jq定义了一种与JSONPath非常相似的JSON查询语言——请参阅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正则表达式) 它是图灵完备的吗?(是的)

我知道的其他选择是

JSONiq specification, which specifies two subtypes of languages: one that hides XML details and provides JS-like syntax, and one that enriches XQuery syntax with JSON constructors and such. Zorba implements JSONiq. Corona, which builds on top of MarkLogic provides a REST interface for storing, managing, and searching XML, JSON, Text and Binary content. MarkLogic 6 and later provide a similar REST interface as Corona out of the box. MarkLogic 8 and later support JSON natively in both their XQuery and Server-side JavaScript environment. You can apply XPath on it.

HTH.