json-duplicate-keys 2024.4.20__py2-none-any.whl → 2024.11.19__py2-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- json_duplicate_keys/__init__.py +254 -288
- {json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/METADATA +15 -11
- json_duplicate_keys-2024.11.19.dist-info/RECORD +6 -0
- json_duplicate_keys-2024.4.20.dist-info/RECORD +0 -6
- {json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/LICENSE +0 -0
- {json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/WHEEL +0 -0
- {json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/top_level.txt +0 -0
json_duplicate_keys/__init__.py
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
try:
|
2
|
+
unicode # Python 2
|
3
|
+
except NameError:
|
4
|
+
unicode = str # Python 3
|
5
|
+
|
1
6
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
2
7
|
# # # # # # # # # # # Normalize Key name # # # # # # # # # # #
|
3
8
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -6,18 +11,16 @@ def normalize_key(name, dupSign_start="{{{", dupSign_end="}}}", _isDebug_=False)
|
|
6
11
|
|
7
12
|
# User input data type validation
|
8
13
|
if type(_isDebug_) != bool: _isDebug_ = False
|
9
|
-
try:
|
10
|
-
if type(name) not in [str, unicode]:
|
11
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
12
|
-
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
13
|
-
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
14
|
-
except Exception as e:
|
15
|
-
if type(name) not in [str]:
|
16
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
17
|
-
if type(dupSign_start) not in [str]: dupSign_start = "{{{"
|
18
|
-
if type(dupSign_end) not in [str]: dupSign_end = "}}}"
|
19
14
|
|
20
|
-
|
15
|
+
if type(name) not in [str, unicode]:
|
16
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
17
|
+
return False
|
18
|
+
|
19
|
+
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
20
|
+
|
21
|
+
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
22
|
+
|
23
|
+
return re.sub('{dupSign_start}_\\d+_{dupSign_end}$'.format(dupSign_start=re.escape(dupSign_start), dupSign_end=re.escape(dupSign_end)), "", name)
|
21
24
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
22
25
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
23
26
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -32,22 +35,21 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
|
|
32
35
|
|
33
36
|
# User input data type validation
|
34
37
|
if type(_isDebug_) != bool: _isDebug_ = False
|
38
|
+
|
35
39
|
if type(ordered_dict) != bool: ordered_dict = False
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
if type(dupSign_start) not in [str]: dupSign_start = "{{{"
|
45
|
-
if type(dupSign_end) not in [str]: dupSign_end = "}}}"
|
40
|
+
|
41
|
+
if type(Jstr) not in [str, unicode]:
|
42
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be str or unicode, not {}\x1b[0m".format(type(Jstr)))
|
43
|
+
return False
|
44
|
+
|
45
|
+
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
46
|
+
|
47
|
+
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
46
48
|
|
47
49
|
def __convert_Jloads_to_Jobj(Jloads, Jobj):
|
48
50
|
if type(Jloads) in [dict, OrderedDict]:
|
49
51
|
for k in Jloads.keys():
|
50
|
-
_key = re.split(dupSign_start_escape_regex+"_
|
52
|
+
_key = re.split(dupSign_start_escape_regex+"_\\d+_"+dupSign_end_escape_regex+"$", k)[0]
|
51
53
|
|
52
54
|
if _key not in Jobj.keys():
|
53
55
|
if type(Jloads[k]) not in [list, dict, OrderedDict]:
|
@@ -62,7 +64,7 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
|
|
62
64
|
|
63
65
|
__convert_Jloads_to_Jobj(Jloads[k], Jobj[_key])
|
64
66
|
else:
|
65
|
-
countObj = len([i for i in Jobj.keys() if _key==re.split(dupSign_start_escape_regex+"_
|
67
|
+
countObj = len([i for i in Jobj.keys() if _key==re.split(dupSign_start_escape_regex+"_\\d+_"+dupSign_end_escape_regex+"$", i)[0]])
|
66
68
|
if type(Jloads[k]) not in [list, dict, OrderedDict]:
|
67
69
|
Jobj[_key+dupSign_start+"_"+str(countObj+1)+"_"+dupSign_end] = Jloads[k]
|
68
70
|
else:
|
@@ -90,8 +92,7 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
|
|
90
92
|
|
91
93
|
try:
|
92
94
|
Jloads = json.loads(Jstr)
|
93
|
-
if ordered_dict:
|
94
|
-
Jloads = json.loads(Jstr, object_pairs_hook=OrderedDict)
|
95
|
+
if ordered_dict: Jloads = json.loads(Jstr, object_pairs_hook=OrderedDict)
|
95
96
|
|
96
97
|
if type(Jloads) in [list, dict, OrderedDict]:
|
97
98
|
dupSign_start_escape = "".join(["\\\\u"+hex(ord(c))[2:].zfill(4) for c in dupSign_start])
|
@@ -135,8 +136,10 @@ def loads(Jstr, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isD
|
|
135
136
|
return JSON_DUPLICATE_KEYS(Jobj)
|
136
137
|
else:
|
137
138
|
if _isDebug_: print("\x1b[31m[-] DataError: Invalid JSON format\x1b[0m")
|
139
|
+
return False
|
138
140
|
except Exception as e:
|
139
141
|
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
142
|
+
return False
|
140
143
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
141
144
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
142
145
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -154,6 +157,7 @@ def load(Jfilepath, dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False,
|
|
154
157
|
return loads(Jstr, dupSign_start=dupSign_start, dupSign_end=dupSign_end, ordered_dict=ordered_dict, _isDebug_=_isDebug_)
|
155
158
|
except Exception as e:
|
156
159
|
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
160
|
+
return False
|
157
161
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
158
162
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
159
163
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -183,46 +187,57 @@ class JSON_DUPLICATE_KEYS:
|
|
183
187
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
184
188
|
# # # # # # # # # # # # # # # get # # # # # # # # # # # # # # #
|
185
189
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
186
|
-
def get(self, name, separator="||", parse_index="$", _isDebug_=False):
|
190
|
+
def get(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
|
187
191
|
import re
|
188
192
|
from collections import OrderedDict
|
189
193
|
|
190
194
|
# User input data type validation
|
191
195
|
if type(_isDebug_) != bool: _isDebug_ = False
|
192
|
-
try:
|
193
|
-
if type(name) not in [str, unicode]:
|
194
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
195
|
-
if type(separator) not in [str, unicode]: separator = "||"
|
196
|
-
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
197
|
-
except Exception as e:
|
198
|
-
if type(name) not in [str]:
|
199
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
200
|
-
if type(separator) not in [str]: separator = "||"
|
201
|
-
if type(parse_index) not in [str]: parse_index = "$"
|
202
196
|
|
203
|
-
if type(
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
Jval = Jobj[int(name_split[i].split(parse_index)[1])]
|
215
|
-
Jobj = Jobj[int(name_split[i].split(parse_index)[1])]
|
216
|
-
else:
|
217
|
-
if _isDebug_: print("\x1b[31m[-] KeyNotFoundError: \x1b[0m"+separator.join(name_split[:i+1]))
|
218
|
-
return "JSON_DUPLICATE_KEYS_ERROR"
|
219
|
-
return Jval
|
220
|
-
except Exception as e:
|
221
|
-
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
222
|
-
return "JSON_DUPLICATE_KEYS_ERROR"
|
223
|
-
else:
|
197
|
+
if type(name) not in [str, unicode]:
|
198
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
199
|
+
return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
|
200
|
+
|
201
|
+
if type(case_insensitive) != bool: case_insensitive = False
|
202
|
+
|
203
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
204
|
+
|
205
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
206
|
+
|
207
|
+
if type(self.getObject()) not in [list, dict, OrderedDict]:
|
224
208
|
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
|
225
|
-
return "JSON_DUPLICATE_KEYS_ERROR"
|
209
|
+
return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
|
210
|
+
|
211
|
+
if re.search(re.escape(separator)+"$", name):
|
212
|
+
if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
|
213
|
+
return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
|
214
|
+
|
215
|
+
Jobj = JSON_DUPLICATE_KEYS(self.__Jobj)
|
216
|
+
Jobj.flatten()
|
217
|
+
Jname = []
|
218
|
+
Jval = self.__Jobj
|
219
|
+
name_split = name.split(separator)
|
220
|
+
for k in Jobj.getObject().keys():
|
221
|
+
if len(k.split(separator)) >= len(name_split):
|
222
|
+
if case_insensitive:
|
223
|
+
if separator.join(k.split(separator)[:len(name_split)]).lower() == name.lower():
|
224
|
+
Jname = k.split(separator)[:len(name_split)]
|
225
|
+
break
|
226
|
+
else:
|
227
|
+
if separator.join(k.split(separator)[:len(name_split)]) == name:
|
228
|
+
Jname = name_split
|
229
|
+
break
|
230
|
+
|
231
|
+
if len(Jname) > 0:
|
232
|
+
for k in Jname:
|
233
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
|
234
|
+
Jval = Jval[int(k.split(parse_index)[1])]
|
235
|
+
else:
|
236
|
+
Jval = Jval[k]
|
237
|
+
return {"name":separator.join(Jname), "value":Jval}
|
238
|
+
else:
|
239
|
+
if _isDebug_: print("\x1b[31m[-] KeyNotFoundError: \x1b[0m"+name)
|
240
|
+
return {"name":name, "value":"JSON_DUPLICATE_KEYS_ERROR"}
|
226
241
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
227
242
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
228
243
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -231,133 +246,80 @@ class JSON_DUPLICATE_KEYS:
|
|
231
246
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
232
247
|
# # # # # # # # # # # # # # # set # # # # # # # # # # # # # # #
|
233
248
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
234
|
-
def set(self, name, value, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
|
249
|
+
def set(self, name, value, case_insensitive=False, separator="||", parse_index="$", dupSign_start="{{{", dupSign_end="}}}", ordered_dict=False, _isDebug_=False):
|
235
250
|
import re
|
236
251
|
from collections import OrderedDict
|
237
252
|
|
238
253
|
# User input data type validation
|
239
254
|
if type(_isDebug_) != bool: _isDebug_ = False
|
255
|
+
|
240
256
|
if type(ordered_dict) != bool: ordered_dict = False
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
if type(self.getObject()) in [list, dict, OrderedDict]:
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
else if typeof self.getObject() is dict
|
283
|
-
=> Add new key ( self.__Jobj[name_split_lastKey] = value )
|
284
|
-
"""
|
285
|
-
# Add duplicate key
|
286
|
-
if self.get(separator.join(name_split), separator=separator, parse_index=parse_index) != "JSON_DUPLICATE_KEYS_ERROR":
|
287
|
-
index = 2
|
288
|
-
while True:
|
289
|
-
if self.get(separator.join(name_split)+dupSign_start+"_"+str(index)+"_"+dupSign_end, separator=separator, parse_index=parse_index) == "JSON_DUPLICATE_KEYS_ERROR":
|
290
|
-
break
|
291
|
-
index += 1
|
292
|
-
|
293
|
-
exec_expression = "self.getObject()"
|
294
|
-
|
295
|
-
name_split[-1] = name_split[-1]+dupSign_start+"_"+str(index)+"_"+dupSign_end
|
296
|
-
for k in name_split:
|
297
|
-
if re.search("^"+re.escape(parse_index)+"\d+"+re.escape(parse_index)+"$", k):
|
298
|
-
exec_expression += "["+k.split(parse_index)[1]+"]"
|
299
|
-
else:
|
300
|
-
exec_expression += "["+repr(k)+"]"
|
301
|
-
|
302
|
-
exec(exec_expression+"="+repr(value))
|
303
|
-
return True
|
304
|
-
# Add new key
|
305
|
-
elif self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index) != "JSON_DUPLICATE_KEYS_ERROR":
|
306
|
-
if type(self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index)) == list:
|
307
|
-
if name_split_lastKey == "":
|
308
|
-
exec_expression = "self.getObject()"
|
309
|
-
|
310
|
-
for k in name_split_first:
|
311
|
-
if re.search("^"+re.escape(parse_index)+"\d+"+re.escape(parse_index)+"$", k):
|
312
|
-
exec_expression += "["+k.split(parse_index)[1]+"]"
|
313
|
-
else:
|
314
|
-
exec_expression += "["+repr(k)+"]"
|
315
|
-
|
316
|
-
exec(exec_expression+".append("+repr(value)+")")
|
317
|
-
else:
|
318
|
-
exec_expression = "self.getObject()"
|
319
|
-
|
320
|
-
for k in name_split_first:
|
321
|
-
if re.search("^"+re.escape(parse_index)+"\d+"+re.escape(parse_index)+"$", k):
|
322
|
-
exec_expression += "["+k.split(parse_index)[1]+"]"
|
323
|
-
else:
|
324
|
-
exec_expression += "["+repr(k)+"]"
|
325
|
-
|
326
|
-
exec(exec_expression+".append({"+repr(name_split_lastKey)+":"+repr(value)+"})")
|
327
|
-
return True
|
328
|
-
elif type(self.get(separator.join(name_split_first), separator=separator, parse_index=parse_index)) == dict:
|
329
|
-
exec_expression = "self.getObject()"
|
330
|
-
|
331
|
-
for k in name_split_first:
|
332
|
-
if re.search("^"+re.escape(parse_index)+"\d+"+re.escape(parse_index)+"$", k):
|
333
|
-
exec_expression += "["+k.split(parse_index)[1]+"]"
|
334
|
-
else:
|
335
|
-
exec_expression += "["+repr(k)+"]"
|
336
|
-
|
337
|
-
exec(exec_expression+"["+repr(name_split_lastKey)+"]="+repr(value))
|
338
|
-
return True
|
339
|
-
else:
|
340
|
-
if _isDebug_: print("\x1b[31m[-] KeyNameNotExistError: {}\x1b[0m".format(separator.join(name_split_first)))
|
341
|
-
# Add new key
|
342
|
-
elif len(name_split_first) == 0:
|
343
|
-
if type(self.getObject()) == list:
|
344
|
-
if name_split_lastKey == "":
|
345
|
-
self.__Jobj.append(value)
|
346
|
-
else:
|
347
|
-
self.__Jobj.append({name_split_lastKey: value})
|
348
|
-
else:
|
349
|
-
self.__Jobj[name_split_lastKey] = value
|
350
|
-
return True
|
351
|
-
else:
|
352
|
-
if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: {}\x1b[0m".format(separator.join(name_split_first)))
|
257
|
+
|
258
|
+
if type(name) not in [str, unicode]:
|
259
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
260
|
+
return False
|
261
|
+
|
262
|
+
if type(case_insensitive) != bool: case_insensitive = False
|
263
|
+
|
264
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
265
|
+
|
266
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
267
|
+
|
268
|
+
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
269
|
+
|
270
|
+
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
271
|
+
|
272
|
+
if type(self.getObject()) not in [list, dict, OrderedDict]:
|
273
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
|
274
|
+
return False
|
275
|
+
|
276
|
+
if re.search(re.escape(separator)+"$", name):
|
277
|
+
if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
|
278
|
+
return False
|
279
|
+
|
280
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", name.split(separator)[-1]):
|
281
|
+
if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: The key name does not end with the list index\x1b[0m")
|
282
|
+
return False
|
283
|
+
|
284
|
+
Jget = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)
|
285
|
+
|
286
|
+
if Jget["value"] != "JSON_DUPLICATE_KEYS_ERROR":
|
287
|
+
index = 2
|
288
|
+
while True:
|
289
|
+
if self.get(Jget["name"]+dupSign_start+"_"+str(index)+"_"+dupSign_end, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["value"] == "JSON_DUPLICATE_KEYS_ERROR":
|
290
|
+
break
|
291
|
+
index += 1
|
292
|
+
|
293
|
+
exec_expression = "self.getObject()"
|
294
|
+
|
295
|
+
for k in (Jget["name"]+dupSign_start+"_"+str(index)+"_"+dupSign_end).split(separator):
|
296
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
|
297
|
+
exec_expression += "["+k.split(parse_index)[1]+"]"
|
353
298
|
else:
|
354
|
-
|
355
|
-
|
356
|
-
|
299
|
+
exec_expression += "["+repr(k)+"]"
|
300
|
+
|
301
|
+
exec(exec_expression+"="+repr(value))
|
302
|
+
return True
|
357
303
|
else:
|
358
|
-
if
|
304
|
+
if len(name.split(separator)) == 1:
|
305
|
+
self.getObject()[name] = value
|
306
|
+
return True
|
307
|
+
else:
|
308
|
+
if self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
|
309
|
+
Jget = self.get(separator.join(name.split(separator)[:-1]), case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)
|
310
|
+
exec_expression = "self.getObject()"
|
359
311
|
|
360
|
-
|
312
|
+
for k in Jget["name"].split(separator):
|
313
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
|
314
|
+
exec_expression += "["+k.split(parse_index)[1]+"]"
|
315
|
+
else:
|
316
|
+
exec_expression += "["+repr(k)+"]"
|
317
|
+
|
318
|
+
exec(exec_expression+"="+repr(value))
|
319
|
+
return True
|
320
|
+
else:
|
321
|
+
if _isDebug_: print("\x1b[31m[-] KeyNameNotExistError: {}\x1b[0m".format(separator.join(Jget["name"].split(separator)[:-1])))
|
322
|
+
return False
|
361
323
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
362
324
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
363
325
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -366,28 +328,29 @@ class JSON_DUPLICATE_KEYS:
|
|
366
328
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
367
329
|
# # # # # # # # # # # # # # update # # # # # # # # # # # # # #
|
368
330
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
369
|
-
def update(self, name, value, separator="||", parse_index="$", _isDebug_=False):
|
331
|
+
def update(self, name, value, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
|
370
332
|
import re
|
371
333
|
|
372
334
|
# User input data type validation
|
373
335
|
if type(_isDebug_) != bool: _isDebug_ = False
|
374
|
-
try:
|
375
|
-
if type(name) not in [str, unicode]:
|
376
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
377
|
-
if type(separator) not in [str, unicode]: separator = "||"
|
378
|
-
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
379
|
-
except Exception as e:
|
380
|
-
if type(name) not in [str]:
|
381
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
382
|
-
if type(separator) not in [str]: separator = "||"
|
383
|
-
if type(parse_index) not in [str]: parse_index = "$"
|
384
336
|
|
385
|
-
if
|
337
|
+
if type(name) not in [str, unicode]:
|
338
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
339
|
+
return False
|
340
|
+
|
341
|
+
if type(case_insensitive) != bool: case_insensitive = False
|
342
|
+
|
343
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
344
|
+
|
345
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
346
|
+
|
347
|
+
if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
|
348
|
+
Jname = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["name"]
|
386
349
|
try:
|
387
350
|
exec_expression = "self.getObject()"
|
388
351
|
|
389
|
-
for k in
|
390
|
-
if re.search("^"+re.escape(parse_index)+"
|
352
|
+
for k in Jname.split(separator):
|
353
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
|
391
354
|
exec_expression += "["+k.split(parse_index)[1]+"]"
|
392
355
|
else:
|
393
356
|
exec_expression += "["+repr(k)+"]"
|
@@ -406,29 +369,29 @@ class JSON_DUPLICATE_KEYS:
|
|
406
369
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
407
370
|
# # # # # # # # # # # # # # delete # # # # # # # # # # # # #
|
408
371
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
409
|
-
def delete(self, name, separator="||", parse_index="$", _isDebug_=False):
|
372
|
+
def delete(self, name, case_insensitive=False, separator="||", parse_index="$", _isDebug_=False):
|
410
373
|
import re
|
411
374
|
|
412
375
|
# User input data type validation
|
413
376
|
if type(_isDebug_) != bool: _isDebug_ = False
|
414
377
|
|
415
|
-
|
416
|
-
if
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
exit("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
423
|
-
if type(separator) not in [str]: separator = "||"
|
424
|
-
if type(parse_index) not in [str]: parse_index = "$"
|
378
|
+
if type(name) not in [str, unicode]:
|
379
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
|
380
|
+
return False
|
381
|
+
|
382
|
+
if type(case_insensitive) != bool: case_insensitive = False
|
383
|
+
|
384
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
425
385
|
|
426
|
-
if
|
386
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
387
|
+
|
388
|
+
if self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index, _isDebug_=_isDebug_)["value"] != "JSON_DUPLICATE_KEYS_ERROR":
|
389
|
+
Jname = self.get(name, case_insensitive=case_insensitive, separator=separator, parse_index=parse_index)["name"]
|
427
390
|
try:
|
428
391
|
exec_expression = "del self.getObject()"
|
429
392
|
|
430
|
-
for k in
|
431
|
-
if re.search("^"+re.escape(parse_index)+"
|
393
|
+
for k in Jname.split(separator):
|
394
|
+
if re.search("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$", k):
|
432
395
|
exec_expression += "["+k.split(parse_index)[1]+"]"
|
433
396
|
else:
|
434
397
|
exec_expression += "["+repr(k)+"]"
|
@@ -457,10 +420,10 @@ class JSON_DUPLICATE_KEYS:
|
|
457
420
|
for k, v in JDKSObject.getObject().items():
|
458
421
|
if type(k) == str and type(name) == str:
|
459
422
|
if re.search(name, k):
|
460
|
-
newJDKSObject.set(k, v, separator="
|
423
|
+
newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
|
461
424
|
else:
|
462
425
|
if name == k:
|
463
|
-
newJDKSObject.set(k, v, separator="
|
426
|
+
newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
|
464
427
|
|
465
428
|
return newJDKSObject
|
466
429
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -481,10 +444,10 @@ class JSON_DUPLICATE_KEYS:
|
|
481
444
|
for k, v in JDKSObject.getObject().items():
|
482
445
|
if type(v) == str and type(value) == str:
|
483
446
|
if re.search(value, v):
|
484
|
-
newJDKSObject.set(k, v, separator="
|
447
|
+
newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
|
485
448
|
else:
|
486
449
|
if value == v:
|
487
|
-
newJDKSObject.set(k, v, separator="
|
450
|
+
newJDKSObject.set(k, v, separator="!!"+separator+"!!", parse_index="!!"+parse_index+"!!", ordered_dict=ordered_dict)
|
488
451
|
|
489
452
|
return newJDKSObject
|
490
453
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -501,22 +464,20 @@ class JSON_DUPLICATE_KEYS:
|
|
501
464
|
|
502
465
|
# User input data type validation
|
503
466
|
if type(_isDebug_) != bool: _isDebug_ = False
|
504
|
-
try:
|
505
|
-
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
506
|
-
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
507
|
-
except Exception as e:
|
508
|
-
if type(dupSign_start) not in [str]: dupSign_start = "{{{"
|
509
|
-
if type(dupSign_end) not in [str]: dupSign_end = "}}}"
|
510
467
|
|
511
|
-
if type(
|
512
|
-
dupSign_start_escape_regex = re.escape(json.dumps({dupSign_start:""})[2:-6])
|
468
|
+
if type(dupSign_start) not in [str, unicode]: dupSign_start = "{{{"
|
513
469
|
|
514
|
-
|
470
|
+
if type(dupSign_end) not in [str, unicode]: dupSign_end = "}}}"
|
515
471
|
|
516
|
-
|
517
|
-
else:
|
472
|
+
if type(self.getObject()) not in [list, dict, OrderedDict]:
|
518
473
|
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
|
519
474
|
return "JSON_DUPLICATE_KEYS_ERROR"
|
475
|
+
|
476
|
+
dupSign_start_escape_regex = re.escape(json.dumps({dupSign_start:""})[2:-6])
|
477
|
+
|
478
|
+
dupSign_end_escape_regex = re.escape(json.dumps({dupSign_end:""})[2:-6])
|
479
|
+
|
480
|
+
return re.sub('{dupSign_start}_\\d+_{dupSign_end}":'.format(dupSign_start=dupSign_start_escape_regex, dupSign_end=dupSign_end_escape_regex), '":', json.dumps(self.getObject(), skipkeys=skipkeys, ensure_ascii=ensure_ascii, check_circular=check_circular, allow_nan=allow_nan, cls=cls, indent=indent, separators=separators, default=default, sort_keys=sort_keys))
|
520
481
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
521
482
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
522
483
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -534,6 +495,7 @@ class JSON_DUPLICATE_KEYS:
|
|
534
495
|
Jfile.close()
|
535
496
|
except Exception as e:
|
536
497
|
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
498
|
+
return False
|
537
499
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
538
500
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
539
501
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -547,52 +509,54 @@ class JSON_DUPLICATE_KEYS:
|
|
547
509
|
|
548
510
|
# User input data type validation
|
549
511
|
if type(_isDebug_) != bool: _isDebug_ = False
|
512
|
+
|
550
513
|
if type(ordered_dict) != bool: ordered_dict = False
|
551
|
-
try:
|
552
|
-
if type(separator) not in [str, unicode]: separator = "||"
|
553
|
-
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
554
|
-
except Exception as e:
|
555
|
-
if type(separator) not in [str]: separator = "||"
|
556
|
-
if type(parse_index) not in [str]: parse_index = "$"
|
557
|
-
|
558
|
-
if type(self.getObject()) in [list, dict, OrderedDict]:
|
559
|
-
if len(self.getObject()) > 0:
|
560
|
-
try:
|
561
|
-
Jflat = dict()
|
562
|
-
if ordered_dict:
|
563
|
-
Jflat = OrderedDict()
|
564
|
-
|
565
|
-
def __convert_Jobj_to_Jflat(Jobj, key=None):
|
566
|
-
if type(Jobj) in [dict, OrderedDict]:
|
567
|
-
if len(Jobj) == 0:
|
568
|
-
Jflat[key] = dict()
|
569
|
-
if ordered_dict:
|
570
|
-
Jflat[key] = OrderedDict()
|
571
|
-
else:
|
572
|
-
for k,v in Jobj.items():
|
573
|
-
_Jobj = v
|
574
|
-
_key = "{key}{separator}{k}".format(key=key,separator=separator,k=k) if key != None else "{k}".format(k=k)
|
575
|
-
|
576
|
-
__convert_Jobj_to_Jflat(_Jobj, _key)
|
577
|
-
elif type(Jobj) == list:
|
578
|
-
if len(Jobj) == 0:
|
579
|
-
Jflat[key] = list()
|
580
|
-
else:
|
581
|
-
for i,v in enumerate(Jobj):
|
582
|
-
_Jobj = v
|
583
|
-
_key = "{key}{separator}{parse_index}{i}{parse_index}".format(key=key, separator=separator, parse_index=parse_index, i=i) if key != None else "{parse_index}{i}{parse_index}".format(parse_index=parse_index, i=i)
|
584
|
-
|
585
|
-
__convert_Jobj_to_Jflat(_Jobj, _key)
|
586
|
-
else:
|
587
|
-
Jflat[key] = Jobj
|
588
514
|
|
589
|
-
|
515
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
590
516
|
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
else:
|
517
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
518
|
+
|
519
|
+
if type(self.getObject()) not in [list, dict, OrderedDict]:
|
595
520
|
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
|
521
|
+
return False
|
522
|
+
|
523
|
+
if len(self.getObject()) > 0:
|
524
|
+
try:
|
525
|
+
Jflat = dict()
|
526
|
+
if ordered_dict:
|
527
|
+
Jflat = OrderedDict()
|
528
|
+
|
529
|
+
def __convert_Jobj_to_Jflat(Jobj, key=None):
|
530
|
+
if type(Jobj) in [dict, OrderedDict]:
|
531
|
+
if len(Jobj) == 0:
|
532
|
+
Jflat[key] = dict()
|
533
|
+
if ordered_dict:
|
534
|
+
Jflat[key] = OrderedDict()
|
535
|
+
else:
|
536
|
+
for k,v in Jobj.items():
|
537
|
+
_Jobj = v
|
538
|
+
_key = "{key}{separator}{k}".format(key=key,separator=separator,k=k) if key != None else "{k}".format(k=k)
|
539
|
+
|
540
|
+
__convert_Jobj_to_Jflat(_Jobj, _key)
|
541
|
+
elif type(Jobj) == list:
|
542
|
+
if len(Jobj) == 0:
|
543
|
+
Jflat[key] = list()
|
544
|
+
else:
|
545
|
+
for i,v in enumerate(Jobj):
|
546
|
+
_Jobj = v
|
547
|
+
_key = "{key}{separator}{parse_index}{i}{parse_index}".format(key=key, separator=separator, parse_index=parse_index, i=i) if key != None else "{parse_index}{i}{parse_index}".format(parse_index=parse_index, i=i)
|
548
|
+
|
549
|
+
__convert_Jobj_to_Jflat(_Jobj, _key)
|
550
|
+
else:
|
551
|
+
Jflat[key] = Jobj
|
552
|
+
|
553
|
+
__convert_Jobj_to_Jflat(self.getObject())
|
554
|
+
|
555
|
+
self.__Jobj = Jflat
|
556
|
+
return True
|
557
|
+
except Exception as e:
|
558
|
+
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
559
|
+
return False
|
596
560
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
597
561
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
598
562
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
@@ -607,42 +571,44 @@ class JSON_DUPLICATE_KEYS:
|
|
607
571
|
|
608
572
|
# User input data type validation
|
609
573
|
if type(_isDebug_) != bool: _isDebug_ = False
|
574
|
+
|
610
575
|
if type(ordered_dict) != bool: ordered_dict = False
|
611
|
-
try:
|
612
|
-
if type(separator) not in [str, unicode]: separator = "||"
|
613
|
-
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
614
|
-
except Exception as e:
|
615
|
-
if type(separator) not in [str]: separator = "||"
|
616
|
-
if type(parse_index) not in [str]: parse_index = "$"
|
617
576
|
|
618
|
-
if type(
|
619
|
-
if len(self.getObject()) > 0:
|
620
|
-
try:
|
621
|
-
Jobj = list() if len([k for k in self.__Jobj.keys() if re.compile("^"+re.escape(parse_index)+"\d+"+re.escape(parse_index)+"$").match(str(k).split(separator)[0])]) == len(self.__Jobj.keys()) else OrderedDict() if ordered_dict else dict()
|
577
|
+
if type(separator) not in [str, unicode]: separator = "||"
|
622
578
|
|
623
|
-
|
624
|
-
Jtmp = Jobj
|
625
|
-
Jkeys = k.split(separator)
|
579
|
+
if type(parse_index) not in [str, unicode]: parse_index = "$"
|
626
580
|
|
627
|
-
|
628
|
-
|
581
|
+
if type(self.getObject()) not in [dict, OrderedDict]:
|
582
|
+
if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
|
583
|
+
return False
|
629
584
|
|
630
|
-
|
631
|
-
|
585
|
+
if len(self.getObject()) > 0:
|
586
|
+
try:
|
587
|
+
Jobj = list() if len([k for k in self.__Jobj.keys() if re.compile("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$").match(str(k).split(separator)[0])]) == len(self.__Jobj.keys()) else OrderedDict() if ordered_dict else dict()
|
632
588
|
|
633
|
-
|
634
|
-
|
589
|
+
for k, v in self.__Jobj.items():
|
590
|
+
Jtmp = Jobj
|
591
|
+
Jkeys = k.split(separator)
|
635
592
|
|
636
|
-
|
637
|
-
|
593
|
+
for count, (Jkey, next_Jkeys) in enumerate(zip(Jkeys, Jkeys[1:] + [v]), 1):
|
594
|
+
v = next_Jkeys if count == len(Jkeys) else list() if re.compile("^"+re.escape(parse_index)+"\\d+"+re.escape(parse_index)+"$").match(next_Jkeys) else OrderedDict() if ordered_dict else dict()
|
638
595
|
|
639
|
-
|
596
|
+
if type(Jtmp) == list:
|
597
|
+
Jkey = int(re.compile(re.escape(parse_index)+"(\\d+)"+re.escape(parse_index)).match(Jkey).group(1))
|
640
598
|
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
599
|
+
while Jkey >= len(Jtmp):
|
600
|
+
Jtmp.append(v)
|
601
|
+
|
602
|
+
elif Jkey not in Jtmp:
|
603
|
+
Jtmp[Jkey] = v
|
604
|
+
|
605
|
+
Jtmp = Jtmp[Jkey]
|
606
|
+
|
607
|
+
self.__Jobj = Jobj
|
608
|
+
return True
|
609
|
+
except Exception as e:
|
610
|
+
if _isDebug_: print("\x1b[31m[-] ExceptionError: {}\x1b[0m".format(e))
|
611
|
+
return False
|
646
612
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
647
613
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
648
614
|
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
{json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/METADATA
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: json-duplicate-keys
|
3
|
-
Version: 2024.
|
3
|
+
Version: 2024.11.19
|
4
4
|
Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
|
5
5
|
Home-page: https://github.com/truocphan/json-duplicate-keys
|
6
6
|
Author: TP Cyber Security
|
@@ -23,12 +23,6 @@ Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
|
|
23
23
|
<a href="#"><img src="https://img.shields.io/github/forks/truocphan/json-duplicate-keys" height=30></a>
|
24
24
|
<a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/truocphan/json-duplicate-keys" height=30></a>
|
25
25
|
<a href="https://github.com/truocphan/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/truocphan/json-duplicate-keys" height=30></a>
|
26
|
-
<a href="https://pypi.org/project/json-duplicate-keys/" target="_blank"><img src="https://img.shields.io/badge/pypi-3775A9?style=for-the-badge&logo=pypi&logoColor=white" height=30></a>
|
27
|
-
<a href="https://www.facebook.com/61550595106970" target="_blank"><img src="https://img.shields.io/badge/Facebook-1877F2?style=for-the-badge&logo=facebook&logoColor=white" height=30></a>
|
28
|
-
<a href="https://twitter.com/TPCyberSec" target="_blank"><img src="https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white" height=30></a>
|
29
|
-
<a href="https://github.com/truocphan" target="_blank"><img src="https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white" height=30></a>
|
30
|
-
<a href="mailto:tpcybersec2023@gmail.com" target="_blank"><img src="https://img.shields.io/badge/Gmail-D14836?style=for-the-badge&logo=gmail&logoColor=white" height=30></a>
|
31
|
-
<a href="https://www.buymeacoffee.com/truocphan" target="_blank"><img src="https://img.shields.io/badge/Buy_Me_A_Coffee-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" height=30></a>
|
32
26
|
</p>
|
33
27
|
|
34
28
|
## Installation
|
@@ -113,9 +107,10 @@ print(JDKSObject.getObject())
|
|
113
107
|
```
|
114
108
|
---
|
115
109
|
|
116
|
-
### JSON_DUPLICATE_KEYS.get(`name`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
110
|
+
### JSON_DUPLICATE_KEYS.get(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
117
111
|
_Get value in the JSON object by `name`_
|
118
112
|
- `name`: the key name of the JSON object. Supported flatten key name format
|
113
|
+
- `case_insensitive`: the key name case (in)sensitive
|
119
114
|
- `separator`:
|
120
115
|
- `parse_index`:
|
121
116
|
- `_isDebug_`: Show/ Hide debug error messages
|
@@ -137,10 +132,11 @@ print(JDKSObject.get("snapshot||author"))
|
|
137
132
|
```
|
138
133
|
---
|
139
134
|
|
140
|
-
### JSON_DUPLICATE_KEYS.set(`name`, `value`, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
|
135
|
+
### JSON_DUPLICATE_KEYS.set(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
|
141
136
|
_Set a new `name` and `value` for the JSON object_
|
142
137
|
- `name`: new key name for the JSON object. Supported flat key name format
|
143
138
|
- `value`: value for key `name`
|
139
|
+
- `case_insensitive`: the key name case (in)sensitive
|
144
140
|
- `separator`:
|
145
141
|
- `parse_index`:
|
146
142
|
- `dupSign_start`:
|
@@ -201,10 +197,11 @@ print(JDKSObject.getObject())
|
|
201
197
|
```
|
202
198
|
---
|
203
199
|
|
204
|
-
### JSON_DUPLICATE_KEYS.update(`name`, `value`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
200
|
+
### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
205
201
|
_Update new `value` for existing `name` in the JSON object_
|
206
202
|
- `name`: the key name of the JSON object. Supported flatten key name format
|
207
203
|
- `value`: new value for key `name`
|
204
|
+
- `case_insensitive`: the key name case (in)sensitive
|
208
205
|
- `separator`:
|
209
206
|
- `parse_index`:
|
210
207
|
- `_isDebug_`: Show/ Hide debug error messages
|
@@ -226,9 +223,10 @@ print(JDKSObject.getObject())
|
|
226
223
|
```
|
227
224
|
---
|
228
225
|
|
229
|
-
### JSON_DUPLICATE_KEYS.delete(`name`, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
226
|
+
### JSON_DUPLICATE_KEYS.delete(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
|
230
227
|
_Delete a key-value pair in a JSON object by key `name`_
|
231
228
|
- `name`: the key name of the JSON object. Supported flatten key name format
|
229
|
+
- `case_insensitive`: the key name case (in)sensitive
|
232
230
|
- `separator`:
|
233
231
|
- `parse_index`:
|
234
232
|
- `_isDebug_`: Show/ Hide debug error messages
|
@@ -395,6 +393,12 @@ print(JDKSObject.getObject())
|
|
395
393
|
---
|
396
394
|
|
397
395
|
## CHANGELOG
|
396
|
+
#### [json-duplicate-keys v2024.11.19](https://github.com/truocphan/json-duplicate-keys/tree/2024.11.19)
|
397
|
+
- **Updated**: Allows getting (`JSON_DUPLICATE_KEYS.get`), setting (`JSON_DUPLICATE_KEYS.set`), updating (`JSON_DUPLICATE_KEYS.update`), deleting (`JSON_DUPLICATE_KEYS.delete`) JSON_DUPLICATE_KEYS objects with case-insensitive key names
|
398
|
+
|
399
|
+
#### [json-duplicate-keys v2024.7.17](https://github.com/truocphan/json-duplicate-keys/tree/2024.7.17)
|
400
|
+
- **Fixed**: issue [#3](https://github.com/truocphan/json-duplicate-keys/issues/3) break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
|
401
|
+
|
398
402
|
#### [json-duplicate-keys v2024.4.20](https://github.com/truocphan/json-duplicate-keys/tree/2024.4.20)
|
399
403
|
- **New**: _filter_values_
|
400
404
|
- **Updated**: _filter_keys_
|
@@ -0,0 +1,6 @@
|
|
1
|
+
json_duplicate_keys/__init__.py,SHA256=K9bg6uSaRnP4JNorn0Y_Chw_ZnRIZoIU0RGxqHFk8-s,26545
|
2
|
+
json_duplicate_keys-2024.11.19.dist-info/LICENSE,SHA256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
|
3
|
+
json_duplicate_keys-2024.11.19.dist-info/METADATA,SHA256=ytf0YHsh6CsnhIZdaihik1ibZkabt6J1QsHkhbpAlno,17673
|
4
|
+
json_duplicate_keys-2024.11.19.dist-info/WHEEL,SHA256=1VPi6hfNQaRRNuEdK_3dv9o8COtLGnHWJghhj4CQ28k,92
|
5
|
+
json_duplicate_keys-2024.11.19.dist-info/top_level.txt,SHA256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
|
6
|
+
json_duplicate_keys-2024.11.19.dist-info/RECORD,,
|
@@ -1,6 +0,0 @@
|
|
1
|
-
json_duplicate_keys/__init__.py,SHA256=ik6YYkU74fqzIGOMUimNt0V8XPcTHvo5C8ZSO_LTADg,29780
|
2
|
-
json_duplicate_keys-2024.4.20.dist-info/LICENSE,SHA256=_hudSGMciUc27wGR8EMKfeb3atJRlf6rbhJtLnel-nc,1093
|
3
|
-
json_duplicate_keys-2024.4.20.dist-info/METADATA,SHA256=OOm04jSjn4RtgRd9pPhdRHPhMf_wEvykdruAluYRIzU,17796
|
4
|
-
json_duplicate_keys-2024.4.20.dist-info/WHEEL,SHA256=1VPi6hfNQaRRNuEdK_3dv9o8COtLGnHWJghhj4CQ28k,92
|
5
|
-
json_duplicate_keys-2024.4.20.dist-info/top_level.txt,SHA256=vdsGrPLVS_l-BFL1i4hCJBY5_-gq4Cwp-11yegA750Y,20
|
6
|
-
json_duplicate_keys-2024.4.20.dist-info/RECORD,,
|
{json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/LICENSE
RENAMED
File without changes
|
File without changes
|
{json_duplicate_keys-2024.4.20.dist-info → json_duplicate_keys-2024.11.19.dist-info}/top_level.txt
RENAMED
File without changes
|