网站首页 > java教程 正文
当我们从网站或者文件获取到复杂结构的 JSON 数据时, 是否因为其多层嵌套结构而头大, 当需要获取指定数据时,还需要写各种条件判断来处理这些取出的数据.
熟悉 Java 的一定使用过 JSONPath 来解析复杂结构的 json 数据, 而不需要解析为 Java 对象再从中获取对应的值.
在 Python 也有相同的模块来支持该功能 -- JmesPath模块. 使用该模块, 可以使我们方便的处理复杂的数据结构.
如何使用
Jmespath 遵循自身的语法结构, 同时对 jsonpath 做了进一步扩展, 有 jsonpath 使用经验的可以快速上手.
# 安装 jmespath
pip install jmespath
# 导入 模块
import jmespath
假如有以下数据
data = {
"name": "小明",
"age": 20,
"hobby": {
"sports": ["篮球", "足球"],
"music": {
"classical": ["小步舞曲", "致爱丽丝"],
"pop": ["青花瓷", "七里香"]
}
}
}
使用传统的方式获取 pop 的第一首歌名
data["hobby"]["music"]["pop"][0]
# 青花瓷
使用 jmespath 获取, 逻辑结构更加清楚
jmespath.search("hobby.music.pop[0]", data)
# 青花瓷
到这里你可以能感觉使用 jmespath 获取数据和常规获取并没太大不同, 那就大错特错了, 这只是最基础的功能.使用下图为完整的语法结构(下方管道示例), 可以从复杂数据中筛选出可用数据, 极大地简化数据处理步骤:
过滤和多结果
jmespath 可以对数据做过滤以及获取多个结果内容, 并且将结果保存为列表或字典
data = {
"people": [
{
"age": 20,
"other": "foo",
"name": "Bob"
},
{
"age": 25,
"other": "bar",
"name": "Fred"
},
{
"age": 30,
"other": "baz",
"name": "George"
}
]
}
# 取people节点, ? 表示条件
# age > 20的结果中取name和age两个值, 保存为列表
jmespath.search("people[?age > `20`].[name, age]", data)
# 运行结果
[
[
"Fred",
25
],
[
"George",
30
]
]
# 同样的条件, 将结果保存为字典
jmespath.search("people[?age > `20`].{name: name, age: age}", data)
# 运行结果
[
{
"name": "Fred",
"age": 25
},
{
"name": "George",
"age": 30
}
]
通过简单的表达式语句, 就可以获取到结果, 相较于原始的需要做循环和条件判断, 非常容易的获取到想要的数据.
使用函数功能
除了使用表达式来过滤内容, jmespath 还提供非常丰富的内置函数对数据做处理, 比如排序(sort), 获取长度(length),计算(abs)等等
# 待处理数据
data = {
"Contents": [
{
"Date": "2014-12-21T05:18:08.000Z",
"Key": "logs/bb",
"Size": 303
},
{
"Date": "2014-12-20T05:19:10.000Z",
"Key": "logs/aa",
"Size": 308
},
{
"Date": "2014-12-20T05:19:12.000Z",
"Key": "logs/qux",
"Size": 297
},
{
"Date": "2014-11-20T05:22:23.000Z",
"Key": "logs/baz",
"Size": 329
},
{
"Date": "2014-12-20T05:25:24.000Z",
"Key": "logs/bar",
"Size": 604
},
{
"Date": "2014-12-20T05:27:12.000Z",
"Key": "logs/foo",
"Size": 647
}
]
}
# 查找Contents内容, &Date表示Date做排序条件
# 结果整理为字典
jmespath.search(
"sort_by(Contents, &Date)[*].{Key: Key, Size: Size}",
data)
# 运行结果
[
{
"Key": "logs/baz",
"Size": 329
},
{
"Key": "logs/aa",
"Size": 308
},
{
"Key": "logs/qux",
"Size": 297
},
{
"Key": "logs/bar",
"Size": 604
},
{
"Key": "logs/foo",
"Size": 647
},
{
"Key": "logs/bb",
"Size": 303
}
]
管道处理
使用 | 表示管道, 将前一个过滤后的结果传递给下一个条件, 通过管道处理, 我们可以逐一使用各种条件来筛选出数据, 最终得到想要的数据, 避免了再使用逻辑代码处理的流程
以下示例通过 3 个条件查找数据:
data = {
"locations": [
{"name": "Seattle", "state": "WA"},
{"name": "New York", "state": "NY"},
{"name": "Bellevue", "state": "WA"},
{"name": "Olympia", "state": "WA"}
]
}
# 1. locations[?state == 'WA'].name 查找state为WA的内容,
# 并取name值结果=>['Seattle', 'Bellevue', 'Olympia']
# 2. sort(@)[-2:] 对前边的结果排序, 并做切片
# 结果 => ['Olympia', 'Seattle']
# 3. {WashingtonCities: join(', ', @)}, 将结果整理为字典, 并用逗号分隔
# 结果 => {'WashingtonCities': 'Olympia, Seattle'}
jmespath.search(
"locations[?state == 'WA'].name | sort(@)[-2:] | {WashingtonCities: join(', ', @)}",
data)
# 运行结果
{
"WashingtonCities": "Olympia, Seattle"
}
以上内容仅仅介绍了一些常用的功能, jmespath 可使用的功能远多于此处内容, 更多的操作可以到官网查看, 里边提供了详细的教程和示例, 不过内容没有中文版本.
猜你喜欢
- 2024-10-28 JavaScript获取json中key所对应的value值的简单方法
- 2024-10-28 为什么JSON.parse会损坏大数字,如何解决这个问题?
- 2024-10-28 深入浅出Json-Schema-Validation(深入浅出stm)
- 2024-10-28 这几个JSON 工具,你是不是错过了
- 2024-10-28 深入解析 JSONPath:从入门到精通(jsonpath解析json)
- 2024-10-28 《Servlet》第18节:HttpServletResponse响应JSON和HTML内容
- 2024-10-28 netty系列之:netty中的核心解码器json
- 2024-10-28 Android JSON(android json to room)
- 2024-10-28 一种适合懒人的JSON解析方式(json解析工具哪个好用)
- 2024-10-28 JAVA实现生成多层JSON格式数据(含源码——三层样例)
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)