网站首页 > 技术教程 正文
JSON,全称 JavaScript Object Notation,2001 的时候由道格拉斯 (Douglas Crockford)所发现并定义。22 岁的大学生才刚毕业,而 22 岁的 JSON 已经成为互联网数据交换的标准之一并且为广大开发者所熟知。
作为开发者之一,也算是阅 JSON 无数,JSON 有胖有瘦,有长有短。短个的 JSON 可以仅仅是仅含一个布尔值的数组:
[true]
而长的 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 输入框,很快就得到了这样的异常提示:
强如 ChatGPT 在又臭又长的文本面前也是摆烂。当然,解决方法也不是没有,分段输入,或者使用编程式调用 ChatGPT 的 API,如果是这样的话,也就回到了起点。
那么,还有没有更好的方式呢?
那必须是 JSON Path!这里我们来使用 He3 的 JSON Path 工具举例,对于上述取 name 字段集合的场景,我们只需要在输入框中输入 $..name 就可以实现:
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:
对于 $..name,我们就知道它表达的是”返回 JSON 数据中所有层级中具有 name 键的值“,那么如果我们要获取所有 age,则可以改成 $..age:
如果我们要获取 man 数组的第一个元素,则可以输入$.human.person.man[0]:
当然, 使用递归下降符号更加方便 $..man[0]:
对于索引引用符 [] ,还有更多高阶操作。
比如要获取第 1、2、3 个元素,则可以输入 $..man[0,1,2]:
对于取 1, 2, 3 这样连续的数组元素,JSON Path 有 [start:end] 更加方便的表达式,上诉可以改成 $..man[0:3]:
?? 这里要注意一下,表达式为 [0,3 是因为取出来的元素包含 start 但不包含 end。
JSON Path 还提供了两种表达式:
- ():表达式,用于进行条件判断或进行逻辑操作。可以在括号内使用比较运算符(如 >, <, == 等)和逻辑运算符(如 &&, ||)来定义条件。例如,(@.length) 表示获取数组中的最后一个元素。
- ?():过滤表达式。在 ?() 中,可以使用任意合法的 JavaScript 表达式来对元素进行筛选。这样的表达式在过滤器内部被计算,并根据其结果决定是否选择或排除当前元素。例如,[?(@.age > 25)] 表示根据元素的 “age” 属性筛选出年龄大于 25 的元素。
有了这两个表达式,我们就可以进一步提高对数据提取的精度。比如现在要获取 man 的最后一个元素,我们可以用 $..man[(@.length-1)]:
@ 表示当前元素,.length 表示当前元素的长度,(@.length-1) 就能够表示获取数组最后一个元素。
如果我们想要过滤 man 字段中 age 大于等于 33 岁的人,则可以用过滤表达式 $..man[?(@. age >= 33)]:
以上,就掌握了 JSON Path 大部分常用的语法,对于剩下的不常用,可以见:JSON Path Plus 实现。
JSON Path 没有一个官方的标准文档,但有一些被广泛接受和使用的实现和文档,JSON Path Plus 就是其中之一,He3 的 JSON Path 工具采用 JSON Path Plus 实现。
回归题目,在如下上万行 JSON 中:
想要查看是否有 friends 叫做 Ellen Rowland 的人,则可以:
猜你喜欢
- 2024-11-21 探索编程之美:揭秘LINQ、Lambda和表达式树的神奇能力
- 2024-11-21 业界首次!云天励飞提出用递归网络模型解决视频人脸关键点定位问题
- 2024-11-21 以Rspack为例,使用Xcode Instruments分析Rust应用性能
- 2024-11-21 编程语言设计与实现之路
- 2024-11-21 Java 工程师成神之路!
- 2024-11-21 前端Rust生态的背后napi-rs如何让Rust与JavaScript可以相互调用
- 2024-11-21 13.6k star,比JsonCpp快20倍,腾讯RapidJSON的用法及原理剖析
- 2024-11-21 Java教程:如何不使用递归实现文件夹的遍历?
- 2024-11-21 Python 新手的5大练手项目,你练了么?
- 2024-11-21 几百行代码实现一个脚本解释器
你 发表评论:
欢迎- 最近发表
-
- 阿里P8大佬总结的Nacos入门笔记,从安装到进阶小白也能轻松学会
- Linux环境下,Jmeter压力测试的搭建及报错解决方法
- Java 在Word中合并单元格时删除重复值
- 解压缩软件哪个好用?4款大多数人常用的软件~
- Hadoop高可用集群搭建及API调用(hadoop3高可用)
- lombok注解@Data没有toString和getter、setter问题
- Apache Felix介绍(apache fineract)
- Spring Boot官方推荐的Docker镜像编译方式-分层jar包
- Gradle 使用手册(gradle详细教程)
- 字节二面:为什么SpringBoot的 jar可以直接运行?
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)