前言:
【技术分享】处理JSON 数据的神器: JMESPath (一) 入门篇 文中介绍了, jmespath的基本使用方法, 如何使用 . 和[ ] 抽取json文档中的目标数据, 管道符 | 的作用和多字段处理 [ ] { }
【技术分享】处理JSON 数据的神器: JMESPath (二) 进阶篇-CSDN博客 介绍了JMESPath 的高阶用法, 包括数据过滤 和使用内置函数进行数据转换
本文继续介绍特殊数据场景下的处理方法--自定义函数
1. 自定义处理函数
需要处理的数据,并不总是规范的,有时需要应对数据格式转换,解析和复杂计算的时候, 内置的函数不能完全满足使用需求, 这时候就需要使用自定义函数处理数据的功能。
下面通过一个示例,来说明自定义函数的用法。
例如我们有一个数据,value是json字符串, 我们需要对其中数据的特定字段进行筛选, 如何通过jmespath 一步实现呢
data = {
"id": 123,
"name": "example",
"nested_json_str": "{\"key1\": \"val1\", \"key2\": {\"subkey\": \"subval\", \"code\": 35}}"
}
数据data的nested_json_str字段中是json dump之后的字符串, 我们需要提取其中的code字段的值并且,将其转换成16进制输出。
需要用到jmespath.search的options参数来实现
import json
import jmespath
from jmespath import Options
from jmespath.functions import Functions
# 定义自定义函数
class CustomFunctions(Functions):
@jmespath.functions.signature({'types': ['number']})
def _func_decimal_to_hex(self, value):
"""十进制转16进制, 返回固定4位长度"""
return '0x'+hex(value)[2:].upper().zfill(4)
@jmespath.functions.signature({'types': ['string']})
def _func_json_loads(self, value):
"""json字符串转对象"""
item = json.loads(value)
return item
# 实例化option对象
custom_options = Options(custom_functions=CustomFunctions())
# jmespath中使用自定义的custom_options 处理数据
pattern = 'nested_json_str'
jmespath.search(pattern, data, options=custom_options)
Out: '{"key1": "val1", "key2": {"subkey": "subval", "code": 35}}'
pattern = 'nested_json_str | json_loads(@).key2.code'
jmespath.search(pattern, data, options=custom_options)
Out: 35
pattern = 'nested_json_str | json_loads(@).key2.code | decimal_to_hex(@)'
jmespath.search(pattern, data, options=custom_options)
Out: '0x0023'
说明: 可以通过继承jmespath提供的Function类, 使用_func前缀自定义函数, 供pattern中进行自定义数据处理的调用, 从而在数据抽取的过程中,即可进行复杂的数据处理,简化代码的调用。 在一些特定的场景, 如数据可视化项目中, 将pattern规则开放给前端调用时,非常好用。
总结
本文介绍了jmespath的更高阶用法, 通过自定义函数,提供查询数据时,应对复杂的数据转换和计算的能力.