Python_实现json数据的jsonPath(精简版)定位及增删改操作

摘要:
param sub_expr:]array_part=result[0]array_part=array_part.lstrip('[').rstrip('']')key_part=sub_expr[:#是空字符串,非数字left_index='0'否则:

基于python实现json数据的jsonPath(精简版)定位及增删改操作

 

by:授客QQ1033553122

 

 

实践环境

win7 64

Python 3.4.0

 

代码

#-*- encoding:utf-8 -*-

 

# author:授客

 

importre

 

defparse_sub_expr(sub_expr):

    '''

    解析字表达式-元素路径的组成部分

    :param sub_expr:

    :return:

    '''

    RIGHT_INDEX_DEFAULT ='200000000' # 右侧索引的默认值 未指定右侧索引时使用,形如key[2:]key[:]

    result = re.findall('[.+]', sub_expr)

    ifresult: # 如果子表达式为数组,形如[1]key[1]key[1:2]key[2:]key[:3]key[:]

        array_part = result[0]

        array_part = array_part.lstrip('[').rstrip(']')

        key_part = sub_expr[:sub_expr.index('[')]

 

        ifkey_part =='$':  # 如果key$,为根,替换为数据变量json_data

            key_part = JSON_DATA_VARNAME

        elifkey_part =='*':

            key_part =='[.+]' # 如果key*,替换为[.+]以便匹配["key1"]["key2"]……

        else:

            key_part ='["%s"]'% key_part

 

        ifarray_part =='*': # 如果数组索引为*,替换为[d+]以便匹配[0][1]……

            array_part ='[d+]'

        else:

            array_part_list = array_part.replace(' ','').split(':')

            left_index = array_part_list[0:1]

            right_index = array_part_list[1:]

 

            ifleft_index:

                left_index = left_index[0]

                if not(left_indexorleft_index.isdigit()): # 为空字符串、非数字

                    left_index ='0'

            else:

                left_index ='0'

 

            ifright_index:

                right_index = right_index[0]

                if not(right_indexorright_index.isdigit()):

                    right_index = RIGHT_INDEX_DEFAULT # 一个比较大的值,

                array_part = left_index +'-'+ right_index

            else:

                array_part = left_index

 

            array_part ='[[%s]]'% array_part  # 数组索引设置为[[n-m]],以便匹配[n],[n+1], ……[m-1]

 

        returnkey_part + array_part

    elifsub_expr =='*':

        sub_expr ='[.+]'

    elifsub_expr =='$':

        sub_expr = JSON_DATA_VARNAME

    else:

        sub_expr ='["%s"]'% sub_expr

 

    returnsub_expr

 

 

defparse_json(json_data, data_struct_link):

    '''

    递归解析json数据结构,存储元素的路径

    :param json_data:

    :param data_struct_link:

    :return:

    '''

    if type(json_data) == type({}): # 字典类型

        keys_list = json_data.keys()

 

        forkeyinkeys_list:

            temp_data_struct_link =  data_struct_link +'["%s"]'% key

            if type(json_data[key])not in[type({}), type([])]: # key对应的value值既不是数组,也不是字典

                data_struct_list.append(temp_data_struct_link)

            else:

                parse_json(json_data[key], temp_data_struct_link)

    elif type(json_data) == type([]): # 数组类型

        array_length = len(json_data)

        forindexin range(0, array_length):

            temp_json_data = json_data[index]

            keys_list = temp_json_data.keys()

 

            forkeyinkeys_list:

                temp_data_struct_link =  data_struct_link +'[%s]["%s"]'% (str(index), key)

                if type(temp_json_data[key])not in[type({}), type([])]: # key对应的value值既不是数组,也不是字典

                    data_struct_list.append(temp_data_struct_link)

                else:

                    parse_json(temp_json_data[key], temp_data_struct_link)

 

if__name__ =='__main__':

    json_data = [{"data": [{

                               "admin":"string|集群负责人|||",

                               "components": [

                                   {

                                       "clusterId":"integer|组件所属的集群id|||",

                                       "createTime":"string|组件创建时间|||",

                                       "description":"string|组件描述|||",

                                       "enabled":"boolean|组件是否开启||false|",

                                       },

                                   {

                                       "clusterId":"integer|组件所属的集群id|||",

                                       "createTime":"string|组件创建时间|||",

                                       "description":"string|组件描述|||",

                                       "enabled":"boolean|组件是否开启||false|",

 

                                       }

                               ],

                               "createTime":"string|集群创建时间|||",

                               "description":"string|集群描述|||",

                               "enabled":"boolean|集群是否开启||false|",

                               "id":"integer|集群id|||",

                               "modifyTime":"string|集群修改时间|||",

                               "name":"string|集群名|||"

                           }],

                  "errMsg":"string||||",

                  "ok":"boolean||||",

                  "status":"integer||||"

                  }]

 

 

    JSON_DATA_VARNAME ='json_data' # 存在json数据的变量名称

    data_struct_list = [] # 用于存放所有json元素路径,形如json_data[0]["data"][0]["components"][0]["enabled"]

    data_struct_link ='json_data'  #  用于临时存放单条json元素路径(的一部分)

    parse_json(json_data, data_struct_link)

 

    print('获取的json元素路径,元素值如下:')

    foritemindata_struct_list:

        print(item,'',  eval(item))

 

    # 测试用表达式

    # expr = '$.data[*].components[0]' # json数据为字典 形如{……}

    # expr = '$[*].data[0:1].components[*]'  # json数据为数组 形如[{……}]

    expr ='data[0:1].components[*]'

    # expr = 'data[0:1].components'

 

    # 解析表达式为正则表达式

    re_pattern =''

    forsub_exprinexpr.split('.'):

        re_pattern += parse_sub_expr(sub_expr)

 

 

    print('元素路径jsonpath表达式为:%s'% expr)

    print('元素路径正则表达式re pattern为:%s'% re_pattern)

 

    print('jsonpath 匹配结果如下:')

    re_pattern = re.compile(re_pattern)

 

    target_set = set() # 匹配结果会有重复值,所以采用集合

    foritemindata_struct_list:

        results = re.findall(re_pattern, item)

        forresultinresults:

            print('匹配的元素路径jsonpath为:%s'% item)

            print('正则匹配结果为:%s'% result)

 

            target = item[0:item.index(result) + len(result)]

            print('供提取数据使用的jsonpath为:%s'% target)

            print('提取的结果值为:%s'% eval(target))

 

            target_set.add(target)

 

    # 通过匹配提取的目标结果,操作json

    foritemintarget_set:

        target = eval(item)

        if type(target) == type({}): #  如果为字典

            # 更改键的值

            target['clusterId'] = 10

 

           # 新增键值对

            target['new_key'] ='key_value'

 

            # 更改键的名称,可以考虑先复制旧的键值,赋值给新的键,然后删除旧的键

            target['description_new'] = target['description']

 

            # 删除键值对

            deltarget['description']

 

        elif type(target) == type([]):

            # 暂不实现

            pass

 

    print(json_data)

 

运行结果截图:

Python_实现json数据的jsonPath(精简版)定位及增删改操作Python_实现json数据的jsonPath(精简版)定位及增删改操作第2张

Python_实现json数据的jsonPath(精简版)定位及增删改操作第3张

Python_实现json数据的jsonPath(精简版)定位及增删改操作第4张

 

 



Python_实现json数据的jsonPath(精简版)定位及增删改操作

Python_实现json数据的jsonPath(精简版)定位及增删改操作

免责声明:文章转载自《Python_实现json数据的jsonPath(精简版)定位及增删改操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇android实现程序开机自启动实用向—总结一些唯一ID生成方式下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

深入理解Binder(二),Binder是什么?

上篇文章深入理解Binder(一),从AIDL谈起我们介绍了AIDL的基本使用,用AIDL两个App的通信是实现了,可是又有小伙伴疑惑了,为什么使用AIDL就能够实现两个App之间的通信?本文我们就来详细说说这个问题。 Binder单从字面上理解,它有活页夹,粘合剂的意思,活页夹可以用来把两个东西夹在一起。在我们的Android系统中,Binder主要用来...

使用UIImageView展现来自网络的图片

本文转载至 http://www.cnblogs.com/chivas/archive/2012/05/21/2512324.html UIImageView:可以通过UIImage加载图片赋给UIImageView,加载后你可以指定显示的位置和大小。 1、初始化 UIImageView  *imageView = [[UIImageView all...

HTML5 Canvas指纹及反追踪介绍

HTML5 Canvas指纹及反追踪介绍 1 Canvas指纹的简介很多网站通过Canvas指纹来跟踪用户。browserleaks[1]是一个在线检测canvas指纹的网站。一般的指纹实现原理即通过canvas画布绘制一些图形,填写一些文字,随后获取图形的base64编码,再经过hash后得到最终的指纹。 下面是一个简单的例子,最终调用toDataUrl...

我要自学网视频免登陆观看破解技巧

不知道写出来之后会不会被封掉!!!   我要自学网上的视频目前我只知道三种,1. 不登陆就可以看的 2.登陆后可以看 3.登陆后花钱可以看的,本文针对第二种 视频提供了一种可以免登陆看视频的方法。(貌似没啥luan用。。。) 第一步:   在浏览器中打开两个网页,一个是第一种视频网页,记为A网页,另一个是第二种视频网页,记为B网页,然后查看B 网页源代码(...

网络渗透资料大全单——漏洞库篇

漏洞库 NVD        ——美国国家漏洞库      →http://nvd.nist.gov/。 CERT        ——美国国家应急响应中心      →https://www.us-cert.gov/ OSVDB        ——开源漏洞库      →http://osvdb.org Bugtraq        —...

HashMap源码分析

final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { HashMap.Node<K,V>[] tab; HashMap.Node<K,V> p; int n, i; // 1.如果t...