java json删除节点_指定json的某个节点进行增、删、改

有时候我们需要对json结构的数据进行更新,或增,或改,或删。

当json层级比较复杂时操作起来是比较麻烦的,得一层层找下去找到要更新的节点才能操作它。

我用python语言封装了一个类,提供三个函数分别用于增删改json的目标节点。

首先我们先确定什么是路径(path);

如json:

dataA={“code”: 0,

“data”: {“areaCode”: “86”, “avatar”: “”, “countryCode”: “86”, “customer_risk_type”: “0”,

“customer”:{“name”:“syc”,“sex”:“m”}},

“valuelist”:[{“expiration”: 1578043337756, “extendStatusBit”: 1, “firstLogin”: “True”, “id”: 11529},

{“expiration”: 1578043337757, “extendStatusBit”: 2, “firstLogin”: “True”, “id”: 11539,

“transaction”:[{“stockcode”:“601235”},{“price”:2.12}]},

{“expiration”: 1578043337758, “extendStatusBit”: 3, “firstLogin”: “True”, “id”: 11549},

{“expiration”: 1578043337759, “extendStatusBit”: 4, “firstLogin”: “True”, “id”: 11559}],

“msg”: “成功”}

对于以上json,我们需要操作data下customer中的name,则name的路径为:/data/customer/name;

再如:列表valuelist下第二个元素中transaction列表下的stockcode,则stockcode的路径为:

/valuelist/(int)1/transaction/(int)0/stockcode

**说明:**由于json允许用字符串类型的数字做key,所以当需要表示列表中第几个元素时前面加个(int)标识;

1、增

def addkv(self,data,path,key=None,value=None):

"""

for example addkv(dataA,'/data/customer','age',30)

:param data: Target JSON

:param path:Location of new field,as '/data/customer'

:param key: new field

:param value:new field value

:return:Added JSON

1

2

3

4

5

6

7

8

:param data:目标JSON

:param path:目标节点的路径,如 '/data/customer',/valuelist/(int)1/transaction/(int)0

:param key: 在该节点下新增的键

:param value:在该节点下新增的键对应的值

:return:新增键值完成后的json

1

2

3

4

5

6

注意:如果目标节点不是字典类型程序会报错,即路径最后一个节点比如/data/customer中的customer的类型必须是字典;

2、删

def delete(self,data,path):

"""

Delete the node of the specified path

:param data:Target JSON

:param path:path

:return:JSON after deleting a node

1

2

3

4

5

6

:param data:目标JSON

:param path:路径

:return:删除节点后返回的json

1

2

3

3、改

def update(self,data,path,newvalue):

"""

Update JSON

:param data:Target JSON

:param path:Route as '/valuelist/(int)0/expiration'

:param newvalue:Modified value

:return:Updated JSON

1

2

3

4

5

6

7

:param data:目标json

:param path:路径

:param newvalue:要改为的新值

:return:返回更新后的json

1

2

3

4

完整代码如下:

#!/usr/bin/env python

#-*- coding:utf-8 -*-

"""

解析json

"""

class rcjson(object):

def resolution(self,local={}):

"""

解析json串中各个字段

:param local:

:return: [{'path': '/code', 'value': 0}, {'path': '/msg', 'value': 'ok'},.........]

"""

def recursive_diff(l,res, path='/'):

delim = '/' if path!= '/' else ''

if(isinstance(l, dict)):

iterl=l.keys()

for k in iterl:

v=l.get(k)

new_path = delim.join([path, k])

recursive_diff(v, res, new_path)

elif(isinstance(l, list)):

enum=enumerate(l, start=0)

for i, item in enum:

new_path = delim.join([path, '(int)'+str(i)])

recursive_diff(item, res, new_path)

else:

res.append({

'path': path,

'value': l

})

result = []

recursive_diff(local, result)

return result

def pathlist(self,paths):

"""

将json节点路径由/../.../转变为list

:param paths:[{'path': '/code', 'value': 0}, {'path': '/msg', 'value': 'ok'},.........]

:return:[{'path': ['code'], 'value': 0}, {'path': ['data', 'areaCode'], 'value': '86'}, {'path': ['data', 'avatar'], 'value': ''},.....]

"""

for path in paths:

routes=path.get('path').split("/")[1:]

newroutes=[]

for route in routes:

if('(int)' in route):

start_loc = route.find('(int)')

len_int=len('(int)')

res_str = route[start_loc+len_int:]

newroutes.append(int(res_str))

else:

newroutes.append(route)

path['path']=newroutes

return paths

def updateValue(self,data,path,newvalue):

"""

修改json中指定的字段的值

:param data:目标json

:param path: '/valuelist/(int)0/expiration' 路径

:param newvalue:修改后的值

:return:[] 或 [{'path': ['code'], 'value': 0}, {'path': ['data', 'areaCode'], 'value': '86'}, {'path': ['data', 'avatar'], 'value': ''},.....]

"""

if(type(data)==dict):

resultStr=self.resolution(data)

index=-1

for pathdic in resultStr:

index=index+1

p=pathdic.get("path")

firstStr=path[:1]

if(firstStr=="/"):

if(p==path):

pathdic["value"]=newvalue

break

else:

if(p=="/"+path):

pathdic["value"] = newvalue

break

if (index + 1 == len(resultStr)):

return [] #没有找到匹配的路径

resultList = self.pathlist(resultStr)

return resultList

else:

return []

def composeDict(self,gkey,result,pv,path,start,end):

"""

组装只有字典的链路

:param gkey: globals对象

:param result: 字典

:param pv: 字典 {'path': ['data', 'customer', 'sex'], 'value': 'm'}

:param path: 列表 ['data', 'customer', 'sex']

:param start:

:param end:

:return:

"""

if (self.isExtend(result, path[0]) == False):

gkey[path[0]] = {}

result[path[0]] = gkey[path[0]]

for i in range(start,end):

dict_i1=gkey[path[i - 1]]

pi=path[i]

flag=self.isExtend(dict_i1,pi)

if(flag== False):

gkey[pi] = {}

dict_i1[pi] = gkey[pi]

lastkey = path[end] # 最后一个key

key_1 = path[end-1] # 倒数第二个key

gkey[key_1][lastkey] = pv.get("value")

return result

def composeJSON(self,resultlist):

"""

组装JSON

:param resultlist: [{'path': ['code'], 'value': 0}, {'path': ['data', 'areaCode'], 'value': '86'}, {'path': ['data', 'avatar'], 'value': ''},......]

:return:json,list也当作json处理先

"""

result={}

gkey=globals()

for pv in resultlist:

path=pv.get('path') #list type ['data', 'areaCode']

if(len(path)==1):

value=pv.get('value')

result[path[0]]=value

elif(len(path)>1):

pathlen = len(path)

self.composeDict(gkey,result,pv,path,1, pathlen - 1)

return result

def dict2list(self,res={}):

"""

之前是列表也按照字典来组装了,现在按照字符串将列表的地方改为列表

:param result:

:return:最终完整的json

"""

def d2l(result={}):

for key,value in result.items(): #result是第一层

if(type(value)==dict):

keys = value.keys() #value是第二层

k0=list(keys)[0]

if (type(k0) == int): #k0是第三层

kv = []

for k in keys:

v = value.get(k)

kv.append(v)

if(type(v)==dict):

d2l(v)

result[key]=kv

else:

d2l(value)

else:

pass

d2l(res)

return res

def update(self,data,path,newvalue):

"""

Update JSON

:param data:Target JSON

:param path:Route as '/valuelist/(int)0/expiration'

:param newvalue:Modified value

:return:Updated JSON

"""

newpaths=self.updateValue(data,path,newvalue)

if(len(newpaths)==0):

return {}

else:

comJSON = rc.composeJSON(newpaths)

lastJson = rc.dict2list(comJSON)

return lastJson

def addkv(self,data,path,key=None,value=None):

"""

for example addkv(dataA,'/data/customer','age',30)

:param data: Target JSON

:param path:Location of new field,as '/data/customer'

:param key: new field

:param value:new field value

:return:Added JSON

"""

resultStr=self.resolution(data)

kv={}

if(key!=None):

kv['path']=path+'/'+key

else:

kv['path'] = path

kv['value']=value

resultStr.append(kv)

newpaths=self.pathlist(resultStr)

if (len(newpaths) == 0):

return {}

else:

comJSON = rc.composeJSON(newpaths)

lastJson = rc.dict2list(comJSON)

return lastJson

def delete(self,data,path):

"""

Delete the node of the specified path

:param data:Target JSON

:param path:path

:return:JSON after deleting a node

"""

paths=self.resolution(data)

templist=[]

for pathv in paths:

p=pathv.get('path')

index=p.find(path)

if(index==0):

other=p[index+len(path):]

if(len(other)>0):

otherOne=other[0]

if((path ==p) or (otherOne=='/')):

pass

else:

templist.append(pathv)

else:

templist.append(pathv)

newpaths =self.pathlist(templist)

if (len(newpaths) == 0):

return {}

else:

comJSON = rc.composeJSON(newpaths)

lastJson = rc.dict2list(comJSON)

return lastJson

def getKeys(self,data):

keysAll_list = []

def getkeys(data): # Traverse all keys of JSON

if (type(data) == type({})):

keys = data.keys()

for key in keys:

value = data.get(key)

if (type(value) != type({}) and type(value) != type([])):

keysAll_list.append(key)

elif (type(value) == type({})):

keysAll_list.append(key)

getkeys(value)

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

keysAll_list.append(key)

for para in value:

if (type(para) == type({}) or type(para) == type([])):

getkeys(para)

else:

keysAll_list.append(para)

getkeys(data)

return keysAll_list

def isExtend(self, ddict={}, tagkey=None): # Check whether the target field tagkey is in data (JSON data)

if (type(ddict) != type({})):

pass

else:

datalen=len(ddict.keys())

if(datalen==0):

pass

else:

key_list = self.getKeys(ddict)

for key in key_list:

if (key == tagkey):

return True

return False

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

验证

if __name__ == '__main__':

rc=rcjson()

dataA={"code": 0,

"data": {"areaCode": "86", "avatar": "", "countryCode": "86", "customer_risk_type": "0","customer":{"name":"syc","sex":"m"}},

"valuelist":[{"expiration": 1578043337756, "extendStatusBit": 1, "firstLogin": "True", "id": 11529},

{"expiration": 1578043337757, "extendStatusBit": 2, "firstLogin": "True", "id": 11539,"transaction":[{"stockcode":"601235"},{"price":2.12}]},

{"expiration": 1578043337758, "extendStatusBit": 3, "firstLogin": "True", "id": 11549},

{"expiration": 1578043337759, "extendStatusBit": 4, "firstLogin": "True", "id": 11559}

],

"msg": "成功"}

#修改

# result=rc.update(dataA,'/valuelist/(int)1/test01/(int)1/price',10.5)

# print(result)

#新增

result=rc.addkv(dataA,'/data/customer/',key='age',value=30)

print(result)

#删除

# result=rc.delete(dataA,'/valuelist/(int)1/test01/(int)0/stockcode')

# print(result)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/267784.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高级 Linux 命令精通指南(2)

xargs 大多数 Linux 命令都会产生输出:文件列表、字符串列表等。但如果要使用其他某个命令并将前一个命令的输出作为参数该怎么办?例如,file 命令显示文件类型(可执行文件、ascii 文本等);您可以处理输出&a…

java如何实现Socket的长连接和短连接

讨论Socket必讨论长连接和短连接 一、长连接和短连接的概念 1、长连接与短连接的概念:前者是整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接;后者是每次请求,都新建一个Socket,处理完一个请求就…

java怎么更改id名_java - 尽管ID已更改为_id,但列'_id'不存在

我已经将我的ID重命名为_id,但仍然得到column _id does not exist ...我错过了什么吗?MyDatabaseelper.javapublic class MyDatabaseHelper extends SQLiteOpenHelper {public static final int DATABASE_VERSION1;public static final String DATABASE_…

NTP搭建(原创)

server 127.127.1.0 fudge 127.127.1.0 stratum 11 driftfile /var/lib/ntp/drift broadcastdelay 0.008 上面是自己作为ntp服务器简单配置 server 192.168.1.10 prefer driftfile /var/lib/ntp/drift broadcastdelay 0.008 上面是选择其他服务器作为ntp服务器简单配置 完事后…

疯狂的java 目录_疯狂创客圈 JAVA 高并发 总目录

无编程不创客,疯狂创客圈,一大波编程高手正在交流、学习中!疯狂创客圈: JAVA 高并发 研习社群, QQ群:104131248(已满) 236263776 (请加此群)疯狂创客圈 经典图书 : 《Netty Zookeeper Redis 高并发实战…

也谈云计算

云计算的介绍和讨论不时见诸于报章网端,但是基本上是各说各话,众说纷纭中让大家仍然感觉云里雾里,不见明路。 本文没有涵盖全部的观点,但却希望提供一种思路,大家共同探讨云的建设。云计算是英文Cloud Computing的翻译…

ubuntu设置静态ip

一、 编辑interfaces文件 (需要修改文件权限) sudo vi /etc/network/interfaces 二、将一下内容添加进去 auto lo iface lo inet loopback auto ens33 iface ens33 inet static address 192.168.0.1(要设置的静态ip) netmas…

车辆入库java程序_java扫描入库及出库,基于谷歌类开发.仅提供完整代码 连接SQL使用,...

java扫描入库及出库,基于谷歌类开发.仅提供完整代码 连接SQL使用,需要自行制作中心服务器,中心服务器代码在本人另一实例里面,请自行下载【实例简介】扫描入库及出库,基于谷歌类开发.仅提供完整代码【实例截图】【核心代码】//直接…

用phpmyadmin更改root密码的方法

首先用root账号登陆phpmyadmin,然后点击左侧进入mysql数据库,在顶部点击“mysql”进入sql输入界面。输入以下命令: update user set passwordpassword(root) where Userroot root为你希望修改的密码,切记不要在数据库中直接手工修…

Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载

效果图&#xff1a; 1、activity_main.xml 描述&#xff1a;定义了六个按钮 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/activity_main&quo…

java中的%nf_java中DecimalFormat四舍五入用法详解

DecimalFormat 是 NumberFormat 的一个具体子类&#xff0c;用于格式化十进制数字。它可以支持不同类型的数&#xff0c;包括整数 (123)、定点数 (123.4)、科学记数法表示的数 (1.23E4)、百分数 (12%) 和金额 ($123)这些内容的本地化。下边先介绍下DecimalFormat的用法&#xf…

org.SLF4J

SLF4J不是具体的日志解决方案&#xff0c;它只服务于各种各样的日志系统。按照官方的说法&#xff0c;SLF4J是一个用于日志系统的简单Facade&#xff0c;允许最终用户在部署其应用时使用其所希望的日志系统。 实际上&#xff0c;SLF4J所提供的核心API是一些接口以及一个LoggerF…

生产者与消费者

package ProConDemo; //创建资源 public class Goods { private String name; //计数器 private int count 1; //创建一个标记 private boolean flag; //创建资源的生产行为 public synchronized void Sale(String name) { //判断标记 while(flag) //有资源就等待 try {wait()…

java业务层怎么设计_java – 在业务逻辑和数据层看起来重叠时分解它们的最佳设计?...

我正在构建一个MVC Web应用程序(使用Spring MVC框架),我对设计特定区域的最佳方法感到有些困惑.应用程序必须与一系列Web服务进行交互,这些Web服务并非真正设计得非常完美,并且本身并不提供很多抽象 – 基本上每个创建/更新/检索/删除操作都有一个Web服务方法.每个“数据类型”…

Lunx运维监控_shark巨菜_基础篇

Lunx运维监控_shark巨菜_基础篇一、监控重要性单单从“监控”两个字来谈&#xff0c;范围之广可以涵盖我们生活的方方面面&#xff0c;我们生活和工作中处处可见视频监控的摄像机&#xff1b;机房中的电压电流监控、干湿计、温度计&#xff1b;值班室的网络监控&#xff0c;网站…

ansible for devops读书笔记第一章

yum -y install ansible ansible --versionmkdir /etc/ansible touch /etc/ansible/hosts[example]   www.example.com ansible example -m ping -u [username]ansible example -a "free -m" -u [username]转载于:https://www.cnblogs.com/guxiaobei/p/8250988.htm…

java项目皮肤包_java swing项目皮肤包+使用方法说明

这是java swing项目皮肤包使用方法说明下载&#xff0c;项目可用的皮肤包&#xff0c;总共四个&#xff0c;自己下载总结的&#xff0c;包含使用代码说明。直接在main函数最开始加入说明代码即可使用~~~加入代码后记得处理异常&#xff01;软件介绍java swing项目皮肤包使用方法…

Oracle中sys和system的区别

1.数据库的启动需要以SYSDBA/SYSOPER身份登录。 2.如果在同一主机上使用IPC连接到数据库使用操作系统授权&#xff0c;登录任何一个用户都可以拥有as sysdba和as sysoper。 3.sys和system用户的区别 SYS用户具有DBA权限&#xff0c;并具有SYS模式。只能通过SYSDBA登录数据库&am…

引用和指针区别

1.引用是一个已存在对象的别名&#xff0c;必须被初始化&#xff0c;且所指对象唯一。 指针本身就是一个对象&#xff0c;可以为空值&#xff0c;能够指向不同的对象。 2.引用本质上是被限制的指针。更安全&#xff0c;更可靠。转载于:https://www.cnblogs.com/Chixinyang/p/82…

WinXP的EFS加密文件如何解密?

根据网上流传的资料&#xff0c;EFS&#xff08;Encrypting File System&#xff09;EFS加密是基于公钥策略的。在使用EFS加密一个文件或文件夹时&#xff0c;系统首先会生成一个由伪随机数组成的FEK(File Encryption Key&#xff0c;文件加密钥匙)&#xff0c;然后将利用FEK和…