在测试工作中,通常都会接触到期望结果数据与实际结果数据一致性比对的测试场景,对于复杂、庞大数据的比对工作。如果依靠人工执行,其成本相当高,难以保障执行结果的一致性(多次执行可能存在偏差),并且重复性极高。因此,通常我们需要考虑如何通过自动化工具实现数据的比对。
本文分享下如何实现Json、字典数据结构的递归解析。
JSON的两种数据结构
1.Key-Value对集合,在Python语言中可以理解为字典(Dict),如下图。
2.有序集合,在Python语言中可以理解为列表(List),如下图。
代码示例
我们以下面这个较为复杂的Json为例。
test_json = {
"code": 200,
"data": [
{
"apps": {
"app_op_seq": [
{
"action": "点击",
"module_name": "聚划算",
"module_type": "resource"
}
]
},
"content": {
"des": {
"company_name": "耐克",
"intent": [
"full"
]
},
"rel": [
{
"des": {
"person_name": "欧阳玖林",
"political_status": "金牌会员"
},
"ont": [
"Company",
"Person"
],
"relIdx": [
0,
"8-9"
],
"relName": "欧阳",
"segs": [
"耐克篮球鞋"
]
}
],
"segs": [
"耐克篮球鞋"
]
},
"content_op": "查询"
}
]
}
实现源码
def json_generator(indict, key_value=None):
"""
递归解析 Json 数据
:param indict:
:param key_value:
:return:
"""
key_value = key_value[:] if key_value else []
if isinstance(indict, dict):
for key, value in indict.items():
tier = - 1
if isinstance(value, dict) and value != {}:
if len(value) == 0:
yield key_value + [key, '{}']
else:
for d in json_generator(value, key_value + [key]):
yield d
elif isinstance(value, list) and value != []:
if len(value) == 0:
yield key_value + [key, '[]']
else:
for v in value:
tier = tier + 1
for d in json_generator(v, key_value + [key + '[{0}]'.format(tier)]):
yield d
else:
yield key_value + [key, value]
else:
if not key_value:
yield indict
else:
yield key_value + [indict]
def structure_flow_sub(json_gen_obj):
"""
解析结果 格式化输出
:param json_gen_obj:
:return: JsonPath:data[0].apps.app_op_seq[0].action
"""
structure = {}
for i in json_generator(json_gen_obj):
if '.'.join(i[:-1]) in structure.keys() and not isinstance(structure['.'.join(i[:-1])], list):
structure['.'.join(i[:-1])] = [structure['.'.join(i[:-1])]]
structure['.'.join(i[:-1])].append(i[-1])
elif '.'.join(i[:-1]) in structure.keys() and isinstance(structure['.'.join(i[:-1])], list):
structure['.'.join(i[:-1])].append(i[-1])
else:
structure['.'.join(i[:-1])] = i[-1]
return structure
def json_path_parse(json_gen_obj):
"""
Json路径解析
:param json_gen_obj:
:return:
"""
structure_List = []
if isinstance(json_gen_obj, dict):
structure = structure_flow_sub(json_gen_obj)
structure_List.append(structure)
return structure_List
if isinstance(json_gen_obj, list):
for i in json_gen_obj:
result = structure_flow_sub(i)
structure_List.append(result)
return structure_List
if __name__ == '__main__':
all_leaf_node_dict = json_path_parse(test_json)
line_number = 0
for k, v in all_leaf_node_dict[0].items():
line_number += 1
print("{line_number} JsonPath:{json_path} Value:{value} ".format(
line_number=line_number, json_path=k, value=v))
解析结果如下
1 JsonPath:code Value:200
2 JsonPath:data[0].apps.app_op_seq[0].action Value:点击
3 JsonPath:data[0].apps.app_op_seq[0].module_name Value:聚划算
4 JsonPath:data[0].apps.app_op_seq[0].module_type Value:resource
5 JsonPath:data[0].content.des.company_name Value:耐克
6 JsonPath:data[0].content.des.intent[0] Value:full
7 JsonPath:data[0].content.rel[0].des.person_name Value:欧阳玖林
8 JsonPath:data[0].content.rel[0].des.political_status Value:金牌会员
9 JsonPath:data[0].content.rel[0].ont[0] Value:Company
10 JsonPath:data[0].content.rel[0].ont[1] Value:Person
11 JsonPath:data[0].content.rel[0].relIdx[0] Value:0
12 JsonPath:data[0].content.rel[0].relIdx[1] Value:8-9
13 JsonPath:data[0].content.rel[0].relName Value:欧阳
14 JsonPath:data[0].content.rel[0].segs[0] Value:耐克篮球鞋
15 JsonPath:data[0].content.segs[0] Value:耐克篮球鞋
16 JsonPath:data[0].content_op Value:查询
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。