处理JSON 数据的神器: JMESPath

2024-07-24 14:08:32 浏览数 (2)

今天发现一个处理json的库jmespath, 开始以为不就是一个jsonpath的改进版么? 没太在意。 然后读了官方文档后,发现比jsonpath强好多,感觉以前怎么没有发现这个库呢。 有时候为了获取一个复杂的路径,费老鼻子劲了。 可以查看官方文档,https://www.osgeo.cn/jmespath/examples.html 例子还是很多的。 jsonpath与jmespath都可以处理json, 它们有什么差别呢?

jsonpath只支持基本的路径表达式和通配符,简单直观。 jmespath支持更多的操作符和函数,支持过滤器,条件表达式,函数等高级特性, 可以灵活的查询json数据。

. 数据过滤 对于列表数据, jmespath支持基于另一个表达式比较来过滤数据元素的方法. 语法为 [?expression] , 表达式中支持运算符

== != < <= > >= , 比较运算符 || && ( ) , 逻辑运算符 ' ' , 转义运算符

代码语言:javascript复制
In [1]: from jmespath import search
 
In [2]: data = {
    ...:   "locations": [
    ...:     {"name": "Seattle", "state": "WA", "size": 83.78},
    ...:     {"name": "New York", "state": "NY", "size": 302.6},
    ...:     {"name": "Bellevue", "state": "WA", "size": 37.51},
    ...:     {"name": "Olympia", "state": "WA", "size": 20.09}
    ...:   ]
    ...: }
 
In [3]: search("locations[?state == 'WA']", data)
Out[3]:
[{'name': 'Seattle', 'state': 'WA', 'size': 83.78},
 {'name': 'Bellevue', 'state': 'WA', 'size': 37.51},
 {'name': 'Olympia', 'state': 'WA', 'size': 20.09}]
 
In [4]: search("locations[?(state=='WA' && name=='Olympia') || state=='NY'] ", data)
Out[4]:
[{'name': 'New York', 'state': 'NY', 'size': 302.6},
 {'name': 'Olympia', 'state': 'WA', 'size': 20.09}]

在上面的表达式中,?state == 'WA'部分是一个筛选表达式。它将判断locations字段对应的列表中state字段是否等于WA, 只有返回为True的数据, 才会被抓取。

第二次解析, ?(state=='WA' && name=='Olympia') || state=='NY' 表达式组合了判断和逻辑运算, 抓取state==WA且name是Olympia的数据, 或者state是NY的数据, 可以看到返回的数据正是这两条.

为了解释转义运算符,我们需要修改一下data数据, 增加一条{"name": "TEST", "state": "TEST"}的数据

代码语言:javascript复制
In [1]: from jmespath import search
 
In [2]: data = {
    ...:   "locations": [
    ...:     {"name": "TEST", "state": "TEST", "size": 20.09},
    ...:     {"name": "New York", "state": "NY", "size": 302.6},
    ...:     {"name": "Bellevue", "state": "WA", "size": 37.51}
    ...:   ]
    ...: }
 
In [3]: search("locations[?name == state]", data)
Out[3]: [{'name': 'TEST', 'state': 'TEST', 'size': 20.09}]
 
In [4]: search("locations[?size>`40`]", data)
Out[4]: [{'name': 'New York', 'state': 'NY', 'size': 302.6}]

筛选的表达式中, 没有引号的数据, 标识的是目标数据中对应字段的值, 所以表达式 ?name == state 筛选的的是 locations中 name和state相等的数据. 包括之前想要筛选state == 'WA' 的数据, 需要用 ' ' 对WA进行转义. 如果比较运算需要对数字进行操作, 需要用到另一个转义符 ,?size>40表达式, 筛选的size大于40的数据.

jmespath 还支持应用内置函数对数据进行筛选,

In [5]: search("locations[?contains(name, 'New')]", data) Out[5]: [{'name': 'New York', 'state': 'NY', 'size': 302.6}] 如表达式 ?contains(name, 'New'), 筛选name字段中包含'New'字符的数据.

  1. 内置函数 jmespath 提供了丰富的内置函数, 支持对数据的简单处理操作. 包括格式转换, 数据断言, 求值等常用的功能. 函数参数中一个特殊字符 @ 将当前结果传递给函数, 类似于Python中的self, 支持的函数如下:

通用 type not_null length to_array to_string to_number 断言 contains starts_with ends_with 数字 abs ceil floor 列表 avg min max sum sort reverse map join 字典 min_by max_by sort_by mege keys values

MESPath Terminal 是一个强大的命令行工具,旨在帮助用户在终端环境下便捷地进行JSON文档的操作和查询。灵感来源于JMESPath。通过实时反馈结果的方式,它为学习和使用JMESPath提供了一个直观且高效的平台。

JMESPath Terminal 基于Python的urwid库构建,实现了对JMESPath表达式的即时解析和显示功能。用户可以直接在命令行中输入JMESPath表达式,结果将立即在右侧窗格中动态呈现。不仅如此,它还支持从文件或管道中接收JSON数据作为输入,提高了操作的灵活性。

键盘快捷键如F5或Ctrl C用于退出程序,Ctrl P用于切换输出模式,而Ctrl ]则可以清空当前表达式。对于支持的终端,鼠标点击还可以用来切换窗口焦点和滚动查看结果。

3、项目及技术应用场景 应用场景: 快速调试:当你正在编写涉及JSON处理的代码时,JMESPath Terminal可以作为一个实时的测试环境,让你快速验证查询表达式的正确性。 数据分析:如果你需要从大型JSON数据集中提取信息,JMESPath Terminal提供了直接操作数据的能力,无需打开复杂的图形化界面。 教育学习:对于初学者,这个工具是学习JMESPath语法的理想选择,因为它允许即时看到结果,从而加深理解。 4、项目特点 实时反馈:输入的每个JMESPath表达式都会立即得到结果展示。 多种输入方式:支持从文件或标准输入读取JSON数据,适应不同的工作流。 灵活的输出模式:可以选择输出表达式本身、结果或者不输出,满足不同需求。 友好交互:提供丰富的键盘快捷键,提升工作效率,并支持部分终端的鼠标操作。 可扩展:源代码简洁明了,适合开发者贡献新功能或自定义配置。 要体验这个神器,只需简单地通过pip安装并运行:

代码语言:javascript复制
$ pip install jmespath-terminal
$ jpterm

0 人点赞