【Python】对比嵌套JSON的不同

43

前言

此对比默认json arry中的顺序相同,在Python中即list中出现的顺序相同。将结果保存在对应的xx_ret中。

import json
import os
import string

# 保存不同的字段
different_ret = []
# 保存缺失的字段
lack_ret = []
# 保存额外的字段
extra_ret = []

# 保存do_check对比时baseJson的前缀
base_json_pre_list = []

# 保存遍历多余字段的前缀
extra_pre_list = []

def do_check(jsonBase,json2):

    # 保证它们是同一种类型
    if isinstance(json2,dict):
        # 思必驰格式判断
        if not isinstance(jsonBase, dict):
            different_ret.append("格式错误")
            return

        for key_c,value_c in json2.items():

            if key_c == "conf" or key_c == "score":
                continue

            base_json_pre_list.append('['+"\""+key_c+"\""+']')
            # TODO: 更复杂的嵌套情况没有仔细想,但是应该不影响
            if key_c in jsonBase:

                tmp_aispeech_json = jsonBase[key_c]
                jsonBase["OC_" + key_c] = jsonBase.pop(key_c)

                # 判断value是否需要继续递归
                if isinstance(value_c, list) or isinstance(value_c, dict):

                    do_check(tmp_aispeech_json, value_c)
                    jsonBase["OC_" + key_c] = tmp_aispeech_json
                    continue

                # 无需继续递归,直接对比
                # 对比value
                if value_c != jsonBase["OC_" + key_c]:
                    # TODO: 收集不同的
                    different_ret.append(''.join(base_json_pre_list))

            else:
                # TODO: 收集缺少的
                lack_ret.append(''.join(base_json_pre_list))
                continue

            base_json_pre_list.pop()

    elif isinstance(json2,list):
        if not isinstance(jsonBase,list):
            different_ret.append("格式错误")
            return
        for item_c_i in range(len(json2)):
            if item_c_i >= len(jsonBase):
                lack_ret.append('['+str(item_c_i)+']')
                return
            base_json_pre_list.append('['+str(item_c_i)+']')
            do_check(jsonBase[item_c_i],json2[item_c_i])
            base_json_pre_list.pop()

# 检查额外的字段
def do_check_extra(json_object):
    if isinstance(json_object,dict):
        for key,value in json_object.items():
            extra_pre_list.append('['+"\""+key+"\""+']')
            if not isinstance(value,list) and not isinstance(value,dict): # v为string
                # 判断key是否被标记过,没有则保存
                if not "OC_" in key:
                    tmp_save_str = ''.join(extra_pre_list)
                    tmp_save_str = tmp_save_str.replace("OC_","")
                    extra_ret.append(tmp_save_str)
            else:
                do_check_extra(value)
            extra_pre_list.pop()

    elif isinstance(json_object,list):
        for item_i in range(len(json_object)):
            # 为了保存前缀,这里需要记录索引
            extra_pre_list.append('['+str(item_i)+']')
            do_check_extra(json_object[item_i])
            extra_pre_list.pop()