如何在万行 JSON 中提取元素?答案是… 🧐

如何在万行 JSON 中提取元素?答案是… 🧐首先 让我来介绍下 JSON Path JSON Path 是一种用于在 JSON 数据中定位和提取特定元素的表达式语言 提供了一种简洁的语法 使得从复杂的 JSON 结构中提取数据变得容易

大家好,欢迎来到IT知识分享网。

JSON,全称 JavaScript Object Notation,2001 的时候由道格拉斯 (Douglas Crockford)所发现并定义。22 岁的大学生才刚毕业,而 22 岁的 JSON 已经成为互联网数据交换的标准之一并且为广大开发者所熟知。

作为开发者之一,也算是阅 JSON 无数,JSON 有胖有瘦,有长有短。短个的 JSON 可以仅仅是仅含一个布尔值的数组:

[true]

而长的 JSON,则可以到达惊人的上万行:

如何在万行 JSON 中提取元素?答案是… 🧐

在阅读长长的 JSON 的过程中,最常遇到的需求是想要提取某一个字段的值,或者遍历数组的元素对象值,而这些,都埋在了深深的 JSON 长河中。

对于一个编程新鸟,最先想到的方式是,通过编程来获取想要的字段,假设有如下结构的 JSON:

{ "human": { "person": { "man": [ { "name": "Jack", "age": "17" }, { "name": "Mike", "age": "32" }, { "name": "John", "age": "23" }, { "name": "David", "age": "41" }, { "name": "Eric", "age": "29" }, { "name": "Chris", "age": "38" }, { "name": "Tom", "age": "27" }, { "name": "Peter", "age": "35" }, { "name": "Robert", "age": "26" }, { "name": "Daniel", "age": "33" } ] } } }

现在我需要获取 man 数组下所有元素中的 name,那么我们肯定会写这边一份 JS 代码:

const nameSet = data.human.person.man.map(manItem => manItem.name)

得益于现代 JavaScript 的语法糖和 API,写出来的代码很简洁。但代码简洁,却背后还有很多问题要考虑:一是需要保存这份代码文件,二是需要运行这份代码的环境,三是需要打印或者保存执行代码的结果,四是需要不断调试这份代码和处理异常边界情况等等

编程新鸟继续思考,在 JSON 中索引值的需求场景很多,笨拙地编程似乎不是高效的方法,于是想要借助最近如火如荼的 ChatGPT:

  • ‍ 我有如上的 JSON 结构,帮我取出 man 字段下所有元素的 name 字段
  • 帮你取出 man 字段下所有元素的 name,结果如下:
    Jack
    Mike,
    John,
    David,
    Eric,
    Chris,
    Tom,
    Peter,
    Robert,
    Daniel









编程新鸟兴冲冲地获得了结果,很开心,但很快就遇到另外一个麻烦了,当把上万的 JSON 粘贴到 ChatGPT 输入框,很快就得到了这样的异常提示:

如何在万行 JSON 中提取元素?答案是… 🧐

强如 ChatGPT 在又臭又长的文本面前也是摆烂。当然,解决方法也不是没有,分段输入,或者使用编程式调用 ChatGPT 的 API,如果是这样的话,也就回到了起点。

那么,还有没有更好的方式呢?

那必须是 JSON Path!这里我们来使用 He3 的 JSON Path 工具举例,对于上述取 name 字段集合的场景,我们只需要在输入框中输入 $..name 就可以实现:

如何在万行 JSON 中提取元素?答案是… 🧐

JSON Path 工具地址:https://t.he3app.com?c9yj

一开始看到 $..name 的时候一脸懵逼,这是什么语法?为什么可以实现?

首先,让我来介绍下 JSON Path:

JSON Path 是一种用于在 JSON 数据中定位和提取特定元素的表达式语言,提供了一种简洁的语法,使得从复杂的 JSON 结构中提取数据变得容易。

简单讲,JSON Path 同 Markdown 一样,一门轻量级的语法,能够提取 JSON 结构片段。

既然 JSON Path 是一门语法,那么有些人就会犯难了,语法就要掌握它的语法点、关键词,有学习成本在。但请相信,JSON Path 学习成本低,学会了之后,你就可以提取特定键的值、遍历数组、根据条件筛选元素、切片等等高端操作,处理 JSON 将游刃有余。

首先先介绍下 JSON Path 的一些常见语法:

  • $:根节点,表示 JSON 数据的最外层。
  • .:子节点操作符,用于访问对象中的属性。
  • []:索引操作符,用于访问数组中的元素或通过条件筛选元素。
  • *:通配符,用于匹配任意属性名或数组索引。
  • ..:递归下降符号,用于搜索嵌套结构中的所有层级。
  • @:当前节点,可以用于在筛选条件中引用当前节点。

假设我们现在在上诉例子 JSON 中新增了一个 “god”: “God” 键值对,并且我们想要用 JSON Path 取得 god 字段,那么就可以用 $.god:

如何在万行 JSON 中提取元素?答案是… 🧐

对于 $..name,我们就知道它表达的是”返回 JSON 数据中所有层级中具有 name 键的值“,那么如果我们要获取所有 age,则可以改成 $..age:

如何在万行 JSON 中提取元素?答案是… 🧐

如果我们要获取 man 数组的第一个元素,则可以输入$.human.person.man[0]:

如何在万行 JSON 中提取元素?答案是… 🧐

当然, 使用递归下降符号更加方便 $..man[0]:

如何在万行 JSON 中提取元素?答案是… 🧐

对于索引引用符 [] ,还有更多高阶操作。

比如要获取第 1、2、3 个元素,则可以输入 $..man[0,1,2]:

如何在万行 JSON 中提取元素?答案是… 🧐

对于取 1, 2, 3 这样连续的数组元素,JSON Path 有 [start:end] 更加方便的表达式,上诉可以改成 $..man[0:3]:

如何在万行 JSON 中提取元素?答案是… 🧐

❗️ 这里要注意一下,表达式为 [0,3 是因为取出来的元素包含 start 但不包含 end。

JSON Path 还提供了两种表达式:

  1. ():表达式,用于进行条件判断或进行逻辑操作。可以在括号内使用比较运算符(如 >, <, == 等)和逻辑运算符(如 &&, ||)来定义条件。例如,(@.length) 表示获取数组中的最后一个元素。
  2. ?():过滤表达式。在 ?() 中,可以使用任意合法的 JavaScript 表达式来对元素进行筛选。这样的表达式在过滤器内部被计算,并根据其结果决定是否选择或排除当前元素。例如,[?(@.age > 25)] 表示根据元素的 “age” 属性筛选出年龄大于 25 的元素。

有了这两个表达式,我们就可以进一步提高对数据提取的精度。比如现在要获取 man 的最后一个元素,我们可以用 $..man[(@.length-1)]:

如何在万行 JSON 中提取元素?答案是… 🧐

@ 表示当前元素,.length 表示当前元素的长度,(@.length-1) 就能够表示获取数组最后一个元素。

如果我们想要过滤 man 字段中 age 大于等于 33 岁的人,则可以用过滤表达式 $..man[?(@. age >= 33)]:

如何在万行 JSON 中提取元素?答案是… 🧐

以上,就掌握了 JSON Path 大部分常用的语法,对于剩下的不常用,可以见:JSON Path Plus 实现。

JSON Path 没有一个官方的标准文档,但有一些被广泛接受和使用的实现和文档,JSON Path Plus 就是其中之一,He3 的 JSON Path 工具采用 JSON Path Plus 实现。

回归题目,在如下上万行 JSON 中:

如何在万行 JSON 中提取元素?答案是… 🧐

想要查看是否有 friends 叫做 Ellen Rowland 的人,则可以:

如何在万行 JSON 中提取元素?答案是… 🧐

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/97921.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信