【问题标题】:JSONPath or other XPath like utility for JSON/Javascript; or Jquery JSONJSONPath 或其他用于 JSON/Javascript 的类似 XPath 的实用程序;或 Jquery JSON
【发布时间】:2009-05-13 16:39:16
【问题描述】:

我一直在研究 JSONPath,虽然它看起来做得很好,但我想知道是否有人使用过它并可以评论它的可用性,或者可以推荐替代方案?如果有一个用于 JQuery 的插件来做这样的事情,那将是 真正 光滑的。我一直在搜索插件并空手而归。无论如何,在我花时间了解 JSONPath(它有一些我不喜欢的方面)之前,或者在我重新发明轮子之前,我想我会看看是否有人对此有看法......

为了让你明白我的意思,想象一下这个 Javascript 对象:

var Characters=[
        {
            id: "CuriousGeorge",
            species:"Monkey",
            mood: "curious",
            appendage: [
                { 
                    type: "hand",
                    side: "left",
                    holding: [ 
                        { id: "Banana" } 
                    ]
                },
                { 
                    type: "hand",
                    side: "right",
                    holding: []
                }, 
                { 
                    type: "foot",
                    side: "left",
                    holding: []
                },
                { 
                    type: "foot",
                    side: "right",
                    holding: [ 
                        { id: "YellowHat" },
                        { id: "Keys" }
                    ]
                }
            ]
        },
        {
            id: "ManInYellowHat",
            species: "Human",
            mood: "angry",
            //...ok, you get it...
        }
    ]

通过 Jquery 选择器之类的东西来访问一些更深层次的对象不是很好吗?

var banana=SomeUtility("Characters holding #Banana").get(0);
var leftHands=SomeUtility("Characters appendage[type=hand][side=left]").get();

(这可能有资格成为世界上最老套的代码示例,但是,嘿,我的孩子们刚刚看了这个。而且由于保密协议,我不能使用真实的示例......)

...而且,为了更有趣,如果我要创造这样的东西,会有人使用它吗?

【问题讨论】:

  • 添加一个 [json] 标签似乎很合适。
  • 有趣的问题。 JSON 的 XPath 等效项将是一件好事,尽管我查看的实现(JSONPath 和 dojox.json.query)似乎出于某种我不明白的原因使用了它们自己的语法。
  • dojo jsonquery 很有趣,但是是的,语法很奇怪,并且试图完成比我想要的更多的事情(因此把事情弄得一团糟)。不过,我应该更仔细地看一下。我总是避开道场,仅仅是因为它看起来过于复杂/复杂——学做简单的事情太多了。这只是我个人的印象

标签: javascript jquery json jsonpath


【解决方案1】:

查看JSON Select - JSON 的类似 CSS 的选择器。

【讨论】:

  • 链接指向错误的网站。应该是 jsonselect.com 吗?
  • @user152468 它不再在 jsonselect.org 上可用。我更新了指向其 GitHub 存储库的链接。
【解决方案2】:

肯定会是一个有用的实用程序。

我的意见是,解决此问题的最佳方法是尽可能与 CSS 选择器保持相似,正如您所指出的。我建议深入了解jquery 的选择器实现。

我会建议类似的东西

var banana = object.function(jsonObect, "holding #Banana");
var leftHands = object.function(jsonObject, "appendage[type=hand][side=left]");

而不是你的用法示例。

我不确定即将到来的native json support 会对此有何影响...

【讨论】:

  • 是的,传入对象是有意义的。昨晚我对此进行了一些修改,并为这些可能性感到鼓舞......更多的未来!
  • 请查看我的答案,我已经创建了一个原型
【解决方案3】:

好的,我已经为此创建了一个原型,可以在这里找到:http://code.google.com/p/jfunk/

它已经被证明对我有用,所以我可能会慢慢改进并将它重构为更好的东西。但如果我得到好的反馈,我可以更快地行动。我也欢迎帮助。

【讨论】:

  • 不错。我只是快速浏览了代码。肯定有这个想法的核心 - 可能会进行一些可能的调整以使其更高效,但现在似乎工作正常。等我有时间的时候,我会在一两个星期内看看它。
  • 是的,甚至没有时间考虑效率——除了意识到 DOM 在这里有一些真正的优势。 但是任何有用的任务可能无法以任何其他方式有效地实现......尽管这会争论重新设计数据......哦,我认为这将是有用的
  • 空仓库,自早期原型阶段以来没有任何变化?
  • @Qrilka,是的,你可以在 code.google.com/p/jfunk/downloads/list 的下载部分找到一些东西,但没有合适的 repo。对这个项目真的没有兴趣,我自己对它的需求消失了,所以......我放弃了它。如果你认为这是个好主意,我不介意把它交给你。虽然,我正在修改 node.js,并且可能决定我可以以某种方式使用它,这取决于我如何创建一些数据结构......
【解决方案4】:

尝试使用 JSPath -- https://github.com/dfilatov/jspath。

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

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

【讨论】:

    【解决方案5】:

    Dojo 的 dojo.getObject 有一个类似这样松散地工作的工具,您可以在其中为要获取的属性提供类似“a.b.c”的路径。

    检查一下:

    http://api.dojotoolkit.org/jsdoc/1.3/dojo.getObject

    我认为它不能很好地理解数组,并且我认为它缺少一种功能齐全的选择器语言,就像您建议的那样。

    至于用法,我编写了一种选择器语言,就像您建议的那样,但对于客户端而言,数组寻址对其特定的对象结构非常专有。

    如果你能做到,我肯定会使用这样的系统,如果我看到我可以提供帮助的领域,甚至可能会做出贡献。

    【讨论】:

    • 我没找到这个,有趣。我肯定感到“对更长的 api 链很有用,你必须测试链中的每个对象”背后的痛苦,因为我多次不得不写像 var a=(b ? c ? d ? b.c.d : null : null 这样的垃圾: 空值); [虽然通常更丑陋,包括其他条件]。尽管如此,总体而言,这似乎并不令人印象深刻......好吧,肯定会增加为 Json/JavascriptObjects 创建类似 Jquery 的并行库的权重,尽管会有明显的必要差异,我怀疑性能会不会一样好......
    • 请查看我的答案,我已经创建了一个原型
    【解决方案6】:

    我刚刚编写了一个客户端 JS-lib 来执行此操作 - 它可以使用 XPath 查询 JSON 结构。

    @jlarson - 使用“defiant.js”,您可以像这样查询您的 JSON 结构(这个库扩展了全局 JSON 对象):

    JSON.search( Characters, '//*[id="Banana"]' );
    



    此调用将返回一个具有匹配节点的数组,并且这些匹配项不会与您的原始 JSON 对象分离(与使用 XML + XPath 时的行为相同)。为了说明我的意思,这里有一段伪(-ish)代码:

    var store = {
        "book": [
            {
                "id": 1,
                "price": 8.95,
                "title": "Sayings of the Century",
                "category": "reference",
                "author": "Nigel Rees"
            },
            {
                "id": 2,
                "price": 22.99,
                "title": "The Lord of the Rings",
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "isbn": "0-395-19395-8"
             }
        ]
    };
    
    var b1 = JSON.search( store, '//book[1]' );
    b1[0].isbn = '12345';
    
    console.log( store.book[0].isbn );
    // 12345
    

    到目前为止,这个库是用于浏览器和客户端的,但我计划最终为 NodeJS 重新编写它。在此处查看 Xpath 评估器;演示功能。还有预先编写的 Xpath 表达式:

    http://defiantjs.com/#xpath_evaluator

    您可以在 Github 上找到该库:
    https://github.com/hbi99/defiant.js

    最后,“defiant.js”中还有更多功能,如果您有兴趣,希望您可以在那里阅读它 (http://defiant.com)

    我希望你会发现它有用。

    【讨论】:

      【解决方案7】:

      似乎有一个新选项:jQuery-JSONPath。似乎正是您所要求的。

      【讨论】:

        【解决方案8】:

        不完全是您要查找的内容,但请查看 object-scan。它有点冗长,但功能更强大,支持更多(复杂)用例。这是一个如何使用它的示例

        // const objectScan = require('object-scan');
        
        const Characters = [{ id: 'CuriousGeorge', species: 'Monkey', mood: 'curious', appendage: [{ type: 'hand', side: 'left', holding: [{ id: 'Banana' }] }, { type: 'hand', side: 'right', holding: [] }, { type: 'foot', side: 'left', holding: [] }, { type: 'foot', side: 'right', holding: [{ id: 'YellowHat' }, { id: 'Keys' }] }] }, { id: 'ManInYellowHat', species: 'Human', mood: 'angry' }];
        
        console.log(objectScan(['**.holding.id'], {
          useArraySelector: false,
          abort: true,
          rtn: 'parent',
          filterFn: ({ value }) => value === 'Banana'
        })(Characters));
        // => { id: 'Banana' }
        
        console.log(objectScan(['**.appendage[*]'], {
          rtn: 'value',
          filterFn: ({ value }) => value.type === 'hand' && value.side === 'left'
        })(Characters));
        // => [ { type: 'hand', side: 'left', holding: [ { id: 'Banana' } ] } ]
        .as-console-wrapper {max-height: 100% !important; top: 0}
        <script src="https://bundle.run/object-scan@13.7.1"></script>

        免责声明:我是object-scan的作者

        请务必查看自述文件。里面有很多例子。

        【讨论】:

          猜你喜欢
          • 2019-03-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-03
          • 1970-01-01
          相关资源
          最近更新 更多