json-duplicate-keys 2025.8.19__tar.gz → 2025.9.9__tar.gz

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.
@@ -1,30 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json-duplicate-keys
3
- Version: 2025.8.19
3
+ Version: 2025.9.9
4
4
  Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
5
5
  Author-email: TP Cyber Security <tpcybersec2023@gmail.com>
6
- License: MIT License
7
-
8
- Copyright (c) 2022 TP Cyber Security
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
- Project-URL: Homepage, https://github.com/tpcybersec/json-duplicate-keys
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/TPCyberSec/json-duplicate-keys
28
8
  Keywords: TPCyberSec,json,duplicate keys,json duplicate keys,flatten,unflatten
29
9
  Classifier: Programming Language :: Python :: 3
30
10
  Classifier: Programming Language :: Python :: Implementation :: Jython
@@ -35,32 +15,34 @@ License-File: LICENSE
35
15
  <h1>JSON Duplicate Keys - PyPI</h1>
36
16
  <i>Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys</i>
37
17
  <br><br>
38
- <a href="https://github.com/tpcybersec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/tpcybersec/json-duplicate-keys" height=30></a>
39
- <a href="#"><img src="https://img.shields.io/github/downloads/tpcybersec/json-duplicate-keys/total" height=30></a>
40
- <a href="#"><img src="https://img.shields.io/github/stars/tpcybersec/json-duplicate-keys" height=30></a>
41
- <a href="#"><img src="https://img.shields.io/github/forks/tpcybersec/json-duplicate-keys" height=30></a>
42
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/tpcybersec/json-duplicate-keys" height=30></a>
43
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/tpcybersec/json-duplicate-keys" height=30></a>
18
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/TPCyberSec/json-duplicate-keys" height=30></a>
19
+ <a href="#"><img src="https://img.shields.io/github/downloads/TPCyberSec/json-duplicate-keys/total" height=30></a>
20
+ <a href="#"><img src="https://img.shields.io/github/stars/TPCyberSec/json-duplicate-keys" height=30></a>
21
+ <a href="#"><img src="https://img.shields.io/github/forks/TPCyberSec/json-duplicate-keys" height=30></a>
22
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/TPCyberSec/json-duplicate-keys" height=30></a>
23
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/TPCyberSec/json-duplicate-keys" height=30></a>
44
24
  <br>
45
25
  <a href="#"><img src="https://img.shields.io/pypi/v/json-duplicate-keys" height=30></a>
46
26
  <a href="#"><img src="https://img.shields.io/pypi/pyversions/json-duplicate-keys" height=30></a>
47
27
  <a href="#"><img src="https://img.shields.io/pypi/dm/json-duplicate-keys" height=30></a>
48
28
  </div>
49
29
 
50
- ## Installation
30
+ ---
31
+ # 🛠️ Installation
51
32
  #### From PyPI:
52
33
  ```console
53
34
  pip install json-duplicate-keys
54
35
  ```
55
36
  #### From Source:
56
37
  ```console
57
- git clone https://github.com/tpcybersec/json-duplicate-keys.git --branch <Branch/Tag>
38
+ git clone https://github.com/TPCyberSec/json-duplicate-keys.git --branch <Branch/Tag>
58
39
  cd json-duplicate-keys
59
40
  python -m build
60
41
  python -m pip install dist/json_duplicate_keys-<version>-py3-none-any.whl
61
42
  ```
62
43
 
63
- ## Basic Usage
44
+ ---
45
+ # 📘 Basic Usage
64
46
  ### normalize_key(`name`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
65
47
  _Normalize Key name_
66
48
  - `name`: key name
@@ -73,8 +55,8 @@ import json_duplicate_keys as jdks
73
55
  print(jdks.normalize_key("version{{{_2_}}}"))
74
56
  # OUTPUT: version
75
57
  ```
76
- ---
77
58
 
59
+ ---
78
60
  ### loads(`Jstr`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
79
61
  _Deserialize a JSON format string to a class `JSON_DUPLICATE_KEYS`_
80
62
  - `Jstr`: a JSON format string
@@ -93,8 +75,8 @@ JDKSObject = jdks.loads(Jstr)
93
75
  print(JDKSObject)
94
76
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE987940>
95
77
  ```
96
- ---
97
78
 
79
+ ---
98
80
  ### load(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
99
81
  _Deserialize a JSON format string from a file to a class `JSON_DUPLICATE_KEYS`_
100
82
  - `Jfilepath`: The path to the file containing the JSON format string
@@ -115,8 +97,8 @@ JDKSObject = jdks.load(Jfilepath)
115
97
  print(JDKSObject)
116
98
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE986D40>
117
99
  ```
118
- ---
119
100
 
101
+ ---
120
102
  ### JSON_DUPLICATE_KEYS.getObject()
121
103
  _Get the JSON object_
122
104
  ```python
@@ -129,8 +111,8 @@ JDKSObject = jdks.loads(Jstr)
129
111
  print(JDKSObject.getObject())
130
112
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
131
113
  ```
132
- ---
133
114
 
115
+ ---
134
116
  ### JSON_DUPLICATE_KEYS.get(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
135
117
  _Get value in the JSON object by `name`_
136
118
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -154,8 +136,8 @@ print(JDKSObject.get("release||$0$"))
154
136
  print(JDKSObject.get("snapshot||author"))
155
137
  # OUTPUT: {'name': 'snapshot||author', 'value': 'truocphan'}
156
138
  ```
157
- ---
158
139
 
140
+ ---
159
141
  ### JSON_DUPLICATE_KEYS.set(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
160
142
  _Set a new `name` and `value` for the JSON object_
161
143
  - `name`: new key name for the JSON object. Supported flat key name format
@@ -200,8 +182,8 @@ JDKSObject.set("snapshot||author", "truocphan")
200
182
  print(JDKSObject.getObject())
201
183
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan'}}
202
184
  ```
203
- ---
204
185
 
186
+ ---
205
187
  ### JSON_DUPLICATE_KEYS.insert(`name`, `value`, `position`=None, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
206
188
  _Insert `value` at `position` in value list of `name`_
207
189
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -228,9 +210,19 @@ JDKSObject.insert("snapshot||release", {'version': '2025.1.1'}, 0)
228
210
 
229
211
  print(JDKSObject.getObject())
230
212
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}, {'version': '2025.1.1'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': '2025.1.1'}, {'version': 'latest'}]}}
213
+
214
+
215
+ JDKSObject = jdks.loads("[]")
216
+
217
+ JDKSObject.insert(None, {"release": []})
218
+ JDKSObject.insert(None, {"author": "truocphan"}, 0)
219
+ JDKSObject.insert("$1$||release", {"version": "2025.9.9"})
220
+
221
+ print(JDKSObject.getObject())
222
+ # OUTPUT: [{'author': 'truocphan'}, {'release': [{'version': '2025.9.9'}]}]
231
223
  ```
232
- ---
233
224
 
225
+ ---
234
226
  ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `allow_new_key`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
235
227
  _Update new `value` for existing `name` or Set a new `name` in the JSON object_
236
228
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -259,8 +251,8 @@ JDKSObject.update("snapshot||version", "latest")
259
251
  print(JDKSObject.getObject())
260
252
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': ['22.3.3', 'latest'], 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': 'latest', 'release': [{'version': 'latest'}]}}
261
253
  ```
262
- ---
263
254
 
255
+ ---
264
256
  ### JSON_DUPLICATE_KEYS.delete(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
265
257
  _Delete a key-value pair in a JSON object by key `name`_
266
258
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -285,8 +277,8 @@ JDKSObject.delete("snapshot")
285
277
  print(JDKSObject.getObject())
286
278
  # OUTPUT: {'author': 'truocphan', 'version{{{_2_}}}': 'latest', 'release': []}
287
279
  ```
288
- ---
289
280
 
281
+ ---
290
282
  ### JSON_DUPLICATE_KEYS.filter_keys(`name`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
291
283
  _Return a `JSON_DUPLICATE_KEYS` object with keys matching a pattern_
292
284
  - `name`:
@@ -306,8 +298,8 @@ print(JDKSObject.filter_keys("version").dumps())
306
298
  print(JDKSObject.dumps())
307
299
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
308
300
  ```
309
- ---
310
301
 
302
+ ---
311
303
  ### JSON_DUPLICATE_KEYS.filter_values(`value`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
312
304
  _Return a `JSON_DUPLICATE_KEYS` object with values matching a pattern_
313
305
  - `value`:
@@ -327,8 +319,8 @@ print(JDKSObject.filter_values("latest").dumps())
327
319
  print(JDKSObject.dumps())
328
320
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
329
321
  ```
330
- ---
331
322
 
323
+ ---
332
324
  ### JSON_DUPLICATE_KEYS.dumps(`dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
333
325
  _Serialize a JSON object to a JSON format string_
334
326
  - `dupSign_start`: Start symbol for marking duplicates (default: `{{{`)
@@ -352,8 +344,8 @@ JDKSObject.delete("snapshot")
352
344
  print(JDKSObject.dumps())
353
345
  # OUTPUT: {"author": "truocphan", "version": "latest", "release": []}
354
346
  ```
355
- ---
356
347
 
348
+ ---
357
349
  ### JSON_DUPLICATE_KEYS.dump(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
358
350
  _Serialize a JSON object to a JSON format string and write to a file_
359
351
  - `Jfilepath`: the path to the file to save the JSON format string
@@ -382,8 +374,8 @@ JDKSObject_load = jdks.load(Jfilepath)
382
374
  print(JDKSObject_load.getObject())
383
375
  # OUTPUT: {'author': 'truocphan', 'version': 'latest', 'release': []}
384
376
  ```
385
- ---
386
377
 
378
+ ---
387
379
  ### JSON_DUPLICATE_KEYS.flatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
388
380
  _Flatten a JSON object to a single key-value pairs_
389
381
  - `separator`: Separator for flatten keys (default: `||`)
@@ -405,8 +397,8 @@ JDKSObject.flatten()
405
397
  print(JDKSObject.getObject())
406
398
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release||$0$||version': 'latest', 'snapshot||author': 'truocphan', 'snapshot||version': '22.3.3', 'snapshot||release||$0$||version': 'latest'}
407
399
  ```
408
- ---
409
400
 
401
+ ---
410
402
  ### JSON_DUPLICATE_KEYS.unflatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
411
403
  _Unflatten a flattened JSON object back to a JSON object_
412
404
  - `separator`: Separator for flatten keys (default: `||`)
@@ -428,37 +420,41 @@ JDKSObject.unflatten()
428
420
  print(JDKSObject.getObject())
429
421
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
430
422
  ```
423
+
431
424
  ---
425
+ # 📝 CHANGELOG
426
+ ### [json-duplicate-keys v2025.9.9](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.9.9)
427
+ - **Fixed**: Inserting a value with an `empty` or `null` name
432
428
 
433
- ## CHANGELOG
434
- #### [json-duplicate-keys v2025.8.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.8.19)
435
- - [**Updated**] Add an exception when loading a non-existent file
436
- - [**Updated**] Dump Unicode characters to a file
429
+ ### [json-duplicate-keys v2025.8.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.8.19)
430
+ - **Updated**: Add an exception when loading a non-existent file
431
+ - **Updated**: Dump Unicode characters to a file
437
432
 
438
- #### [json-duplicate-keys v2025.7.1](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.7.1)
439
- - [**Updated**] Fixed some issues when loading JSON strings with `skipDuplicated` option
440
- - [**Updated**] Allow loading of JSON data in byte string format
441
- - [**Updated**] Issue with getting and setting an empty list
433
+ ### [json-duplicate-keys v2025.7.1](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.7.1)
434
+ - **Updated**: Fixed some issues when loading JSON strings with `skipDuplicated` option
435
+ - **Updated**: Allow loading of JSON data in byte string format
436
+ - **Updated**: Issue with getting and setting an empty list
442
437
 
443
- #### [json-duplicate-keys v2025.6.6](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.6.6)
444
- - [**Updated**] Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
438
+ ### [json-duplicate-keys v2025.6.6](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.6.6)
439
+ - **Updated** Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
445
440
 
446
- #### [json-duplicate-keys v2024.12.12](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.12.12)
441
+ ### [json-duplicate-keys v2024.12.12](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.12.12)
447
442
  - **New**: _insert_ function
448
443
 
449
- #### [json-duplicate-keys v2024.11.28](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.28)
444
+ ### [json-duplicate-keys v2024.11.28](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.28)
450
445
  - **Fixed**: Add subkey name to empty dict of existing key name
451
446
 
452
- #### [json-duplicate-keys v2024.11.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.19)
447
+ ### [json-duplicate-keys v2024.11.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.19)
453
448
  - **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
454
449
 
455
- #### [json-duplicate-keys v2024.7.17](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.7.17)
450
+ ### [json-duplicate-keys v2024.7.17](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.7.17)
456
451
  - **Fixed**: issue #3 break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
457
452
 
458
- #### [json-duplicate-keys v2024.4.20](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.4.20)
453
+ ### [json-duplicate-keys v2024.4.20](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.4.20)
459
454
  - **New**: _filter_values_
460
455
  - **Updated**: _filter_keys_
461
456
 
462
- #### [json-duplicate-keys v2024.3.24](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.3.24)
457
+ ### [json-duplicate-keys v2024.3.24](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.3.24)
463
458
  - **Updated**: _normalize_key_, _loads_, _get_, _set_, _update_, _delete_
459
+
464
460
  ---
@@ -2,32 +2,34 @@
2
2
  <h1>JSON Duplicate Keys - PyPI</h1>
3
3
  <i>Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys</i>
4
4
  <br><br>
5
- <a href="https://github.com/tpcybersec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/tpcybersec/json-duplicate-keys" height=30></a>
6
- <a href="#"><img src="https://img.shields.io/github/downloads/tpcybersec/json-duplicate-keys/total" height=30></a>
7
- <a href="#"><img src="https://img.shields.io/github/stars/tpcybersec/json-duplicate-keys" height=30></a>
8
- <a href="#"><img src="https://img.shields.io/github/forks/tpcybersec/json-duplicate-keys" height=30></a>
9
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/tpcybersec/json-duplicate-keys" height=30></a>
10
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/tpcybersec/json-duplicate-keys" height=30></a>
5
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/TPCyberSec/json-duplicate-keys" height=30></a>
6
+ <a href="#"><img src="https://img.shields.io/github/downloads/TPCyberSec/json-duplicate-keys/total" height=30></a>
7
+ <a href="#"><img src="https://img.shields.io/github/stars/TPCyberSec/json-duplicate-keys" height=30></a>
8
+ <a href="#"><img src="https://img.shields.io/github/forks/TPCyberSec/json-duplicate-keys" height=30></a>
9
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/TPCyberSec/json-duplicate-keys" height=30></a>
10
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/TPCyberSec/json-duplicate-keys" height=30></a>
11
11
  <br>
12
12
  <a href="#"><img src="https://img.shields.io/pypi/v/json-duplicate-keys" height=30></a>
13
13
  <a href="#"><img src="https://img.shields.io/pypi/pyversions/json-duplicate-keys" height=30></a>
14
14
  <a href="#"><img src="https://img.shields.io/pypi/dm/json-duplicate-keys" height=30></a>
15
15
  </div>
16
16
 
17
- ## Installation
17
+ ---
18
+ # 🛠️ Installation
18
19
  #### From PyPI:
19
20
  ```console
20
21
  pip install json-duplicate-keys
21
22
  ```
22
23
  #### From Source:
23
24
  ```console
24
- git clone https://github.com/tpcybersec/json-duplicate-keys.git --branch <Branch/Tag>
25
+ git clone https://github.com/TPCyberSec/json-duplicate-keys.git --branch <Branch/Tag>
25
26
  cd json-duplicate-keys
26
27
  python -m build
27
28
  python -m pip install dist/json_duplicate_keys-<version>-py3-none-any.whl
28
29
  ```
29
30
 
30
- ## Basic Usage
31
+ ---
32
+ # 📘 Basic Usage
31
33
  ### normalize_key(`name`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
32
34
  _Normalize Key name_
33
35
  - `name`: key name
@@ -40,8 +42,8 @@ import json_duplicate_keys as jdks
40
42
  print(jdks.normalize_key("version{{{_2_}}}"))
41
43
  # OUTPUT: version
42
44
  ```
43
- ---
44
45
 
46
+ ---
45
47
  ### loads(`Jstr`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
46
48
  _Deserialize a JSON format string to a class `JSON_DUPLICATE_KEYS`_
47
49
  - `Jstr`: a JSON format string
@@ -60,8 +62,8 @@ JDKSObject = jdks.loads(Jstr)
60
62
  print(JDKSObject)
61
63
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE987940>
62
64
  ```
63
- ---
64
65
 
66
+ ---
65
67
  ### load(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
66
68
  _Deserialize a JSON format string from a file to a class `JSON_DUPLICATE_KEYS`_
67
69
  - `Jfilepath`: The path to the file containing the JSON format string
@@ -82,8 +84,8 @@ JDKSObject = jdks.load(Jfilepath)
82
84
  print(JDKSObject)
83
85
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE986D40>
84
86
  ```
85
- ---
86
87
 
88
+ ---
87
89
  ### JSON_DUPLICATE_KEYS.getObject()
88
90
  _Get the JSON object_
89
91
  ```python
@@ -96,8 +98,8 @@ JDKSObject = jdks.loads(Jstr)
96
98
  print(JDKSObject.getObject())
97
99
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
98
100
  ```
99
- ---
100
101
 
102
+ ---
101
103
  ### JSON_DUPLICATE_KEYS.get(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
102
104
  _Get value in the JSON object by `name`_
103
105
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -121,8 +123,8 @@ print(JDKSObject.get("release||$0$"))
121
123
  print(JDKSObject.get("snapshot||author"))
122
124
  # OUTPUT: {'name': 'snapshot||author', 'value': 'truocphan'}
123
125
  ```
124
- ---
125
126
 
127
+ ---
126
128
  ### JSON_DUPLICATE_KEYS.set(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
127
129
  _Set a new `name` and `value` for the JSON object_
128
130
  - `name`: new key name for the JSON object. Supported flat key name format
@@ -167,8 +169,8 @@ JDKSObject.set("snapshot||author", "truocphan")
167
169
  print(JDKSObject.getObject())
168
170
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan'}}
169
171
  ```
170
- ---
171
172
 
173
+ ---
172
174
  ### JSON_DUPLICATE_KEYS.insert(`name`, `value`, `position`=None, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
173
175
  _Insert `value` at `position` in value list of `name`_
174
176
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -195,9 +197,19 @@ JDKSObject.insert("snapshot||release", {'version': '2025.1.1'}, 0)
195
197
 
196
198
  print(JDKSObject.getObject())
197
199
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}, {'version': '2025.1.1'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': '2025.1.1'}, {'version': 'latest'}]}}
200
+
201
+
202
+ JDKSObject = jdks.loads("[]")
203
+
204
+ JDKSObject.insert(None, {"release": []})
205
+ JDKSObject.insert(None, {"author": "truocphan"}, 0)
206
+ JDKSObject.insert("$1$||release", {"version": "2025.9.9"})
207
+
208
+ print(JDKSObject.getObject())
209
+ # OUTPUT: [{'author': 'truocphan'}, {'release': [{'version': '2025.9.9'}]}]
198
210
  ```
199
- ---
200
211
 
212
+ ---
201
213
  ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `allow_new_key`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
202
214
  _Update new `value` for existing `name` or Set a new `name` in the JSON object_
203
215
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -226,8 +238,8 @@ JDKSObject.update("snapshot||version", "latest")
226
238
  print(JDKSObject.getObject())
227
239
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': ['22.3.3', 'latest'], 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': 'latest', 'release': [{'version': 'latest'}]}}
228
240
  ```
229
- ---
230
241
 
242
+ ---
231
243
  ### JSON_DUPLICATE_KEYS.delete(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
232
244
  _Delete a key-value pair in a JSON object by key `name`_
233
245
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -252,8 +264,8 @@ JDKSObject.delete("snapshot")
252
264
  print(JDKSObject.getObject())
253
265
  # OUTPUT: {'author': 'truocphan', 'version{{{_2_}}}': 'latest', 'release': []}
254
266
  ```
255
- ---
256
267
 
268
+ ---
257
269
  ### JSON_DUPLICATE_KEYS.filter_keys(`name`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
258
270
  _Return a `JSON_DUPLICATE_KEYS` object with keys matching a pattern_
259
271
  - `name`:
@@ -273,8 +285,8 @@ print(JDKSObject.filter_keys("version").dumps())
273
285
  print(JDKSObject.dumps())
274
286
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
275
287
  ```
276
- ---
277
288
 
289
+ ---
278
290
  ### JSON_DUPLICATE_KEYS.filter_values(`value`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
279
291
  _Return a `JSON_DUPLICATE_KEYS` object with values matching a pattern_
280
292
  - `value`:
@@ -294,8 +306,8 @@ print(JDKSObject.filter_values("latest").dumps())
294
306
  print(JDKSObject.dumps())
295
307
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
296
308
  ```
297
- ---
298
309
 
310
+ ---
299
311
  ### JSON_DUPLICATE_KEYS.dumps(`dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
300
312
  _Serialize a JSON object to a JSON format string_
301
313
  - `dupSign_start`: Start symbol for marking duplicates (default: `{{{`)
@@ -319,8 +331,8 @@ JDKSObject.delete("snapshot")
319
331
  print(JDKSObject.dumps())
320
332
  # OUTPUT: {"author": "truocphan", "version": "latest", "release": []}
321
333
  ```
322
- ---
323
334
 
335
+ ---
324
336
  ### JSON_DUPLICATE_KEYS.dump(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
325
337
  _Serialize a JSON object to a JSON format string and write to a file_
326
338
  - `Jfilepath`: the path to the file to save the JSON format string
@@ -349,8 +361,8 @@ JDKSObject_load = jdks.load(Jfilepath)
349
361
  print(JDKSObject_load.getObject())
350
362
  # OUTPUT: {'author': 'truocphan', 'version': 'latest', 'release': []}
351
363
  ```
352
- ---
353
364
 
365
+ ---
354
366
  ### JSON_DUPLICATE_KEYS.flatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
355
367
  _Flatten a JSON object to a single key-value pairs_
356
368
  - `separator`: Separator for flatten keys (default: `||`)
@@ -372,8 +384,8 @@ JDKSObject.flatten()
372
384
  print(JDKSObject.getObject())
373
385
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release||$0$||version': 'latest', 'snapshot||author': 'truocphan', 'snapshot||version': '22.3.3', 'snapshot||release||$0$||version': 'latest'}
374
386
  ```
375
- ---
376
387
 
388
+ ---
377
389
  ### JSON_DUPLICATE_KEYS.unflatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
378
390
  _Unflatten a flattened JSON object back to a JSON object_
379
391
  - `separator`: Separator for flatten keys (default: `||`)
@@ -395,37 +407,41 @@ JDKSObject.unflatten()
395
407
  print(JDKSObject.getObject())
396
408
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
397
409
  ```
410
+
398
411
  ---
412
+ # 📝 CHANGELOG
413
+ ### [json-duplicate-keys v2025.9.9](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.9.9)
414
+ - **Fixed**: Inserting a value with an `empty` or `null` name
399
415
 
400
- ## CHANGELOG
401
- #### [json-duplicate-keys v2025.8.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.8.19)
402
- - [**Updated**] Add an exception when loading a non-existent file
403
- - [**Updated**] Dump Unicode characters to a file
416
+ ### [json-duplicate-keys v2025.8.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.8.19)
417
+ - **Updated**: Add an exception when loading a non-existent file
418
+ - **Updated**: Dump Unicode characters to a file
404
419
 
405
- #### [json-duplicate-keys v2025.7.1](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.7.1)
406
- - [**Updated**] Fixed some issues when loading JSON strings with `skipDuplicated` option
407
- - [**Updated**] Allow loading of JSON data in byte string format
408
- - [**Updated**] Issue with getting and setting an empty list
420
+ ### [json-duplicate-keys v2025.7.1](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.7.1)
421
+ - **Updated**: Fixed some issues when loading JSON strings with `skipDuplicated` option
422
+ - **Updated**: Allow loading of JSON data in byte string format
423
+ - **Updated**: Issue with getting and setting an empty list
409
424
 
410
- #### [json-duplicate-keys v2025.6.6](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.6.6)
411
- - [**Updated**] Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
425
+ ### [json-duplicate-keys v2025.6.6](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.6.6)
426
+ - **Updated** Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
412
427
 
413
- #### [json-duplicate-keys v2024.12.12](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.12.12)
428
+ ### [json-duplicate-keys v2024.12.12](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.12.12)
414
429
  - **New**: _insert_ function
415
430
 
416
- #### [json-duplicate-keys v2024.11.28](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.28)
431
+ ### [json-duplicate-keys v2024.11.28](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.28)
417
432
  - **Fixed**: Add subkey name to empty dict of existing key name
418
433
 
419
- #### [json-duplicate-keys v2024.11.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.19)
434
+ ### [json-duplicate-keys v2024.11.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.19)
420
435
  - **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
421
436
 
422
- #### [json-duplicate-keys v2024.7.17](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.7.17)
437
+ ### [json-duplicate-keys v2024.7.17](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.7.17)
423
438
  - **Fixed**: issue #3 break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
424
439
 
425
- #### [json-duplicate-keys v2024.4.20](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.4.20)
440
+ ### [json-duplicate-keys v2024.4.20](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.4.20)
426
441
  - **New**: _filter_values_
427
442
  - **Updated**: _filter_keys_
428
443
 
429
- #### [json-duplicate-keys v2024.3.24](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.3.24)
444
+ ### [json-duplicate-keys v2024.3.24](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.3.24)
430
445
  - **Updated**: _normalize_key_, _loads_, _get_, _set_, _update_, _delete_
446
+
431
447
  ---
@@ -362,8 +362,8 @@ class JSON_DUPLICATE_KEYS:
362
362
  # User input data type validation
363
363
  if type(_isDebug_) != bool: _isDebug_ = False
364
364
 
365
- if type(name) not in [str, unicode]:
366
- if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str or unicode, not {}\x1b[0m".format(type(name)))
365
+ if type(name) not in [str, unicode, type(None)]:
366
+ if _isDebug_: print("\x1b[31m[-] DataTypeError: the KEY name must be str, unicode or None, not {}\x1b[0m".format(type(name)))
367
367
  return False
368
368
 
369
369
  if type(position) != int: position = None
@@ -381,6 +381,12 @@ class JSON_DUPLICATE_KEYS:
381
381
  if type(self.getObject()) not in [list, dict, OrderedDict]:
382
382
  if _isDebug_: print("\x1b[31m[-] DataTypeError: the JSON object must be list, dict or OrderedDict, not {}\x1b[0m".format(type(self.getObject())))
383
383
  return False
384
+
385
+ if (name is None or name == "") and type(self.getObject()) == list:
386
+ if position is None: position = len(self.getObject())
387
+
388
+ self.getObject().insert(position, value)
389
+ return True
384
390
 
385
391
  if re.search(re.escape(separator)+"$", name):
386
392
  if _isDebug_: print("\x1b[31m[-] KeyNameInvalidError: \x1b[0m"+name)
@@ -1,30 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json-duplicate-keys
3
- Version: 2025.8.19
3
+ Version: 2025.9.9
4
4
  Summary: Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys
5
5
  Author-email: TP Cyber Security <tpcybersec2023@gmail.com>
6
- License: MIT License
7
-
8
- Copyright (c) 2022 TP Cyber Security
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
- Project-URL: Homepage, https://github.com/tpcybersec/json-duplicate-keys
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/TPCyberSec/json-duplicate-keys
28
8
  Keywords: TPCyberSec,json,duplicate keys,json duplicate keys,flatten,unflatten
29
9
  Classifier: Programming Language :: Python :: 3
30
10
  Classifier: Programming Language :: Python :: Implementation :: Jython
@@ -35,32 +15,34 @@ License-File: LICENSE
35
15
  <h1>JSON Duplicate Keys - PyPI</h1>
36
16
  <i>Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys</i>
37
17
  <br><br>
38
- <a href="https://github.com/tpcybersec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/tpcybersec/json-duplicate-keys" height=30></a>
39
- <a href="#"><img src="https://img.shields.io/github/downloads/tpcybersec/json-duplicate-keys/total" height=30></a>
40
- <a href="#"><img src="https://img.shields.io/github/stars/tpcybersec/json-duplicate-keys" height=30></a>
41
- <a href="#"><img src="https://img.shields.io/github/forks/tpcybersec/json-duplicate-keys" height=30></a>
42
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/tpcybersec/json-duplicate-keys" height=30></a>
43
- <a href="https://github.com/tpcybersec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/tpcybersec/json-duplicate-keys" height=30></a>
18
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/releases/"><img src="https://img.shields.io/github/release/TPCyberSec/json-duplicate-keys" height=30></a>
19
+ <a href="#"><img src="https://img.shields.io/github/downloads/TPCyberSec/json-duplicate-keys/total" height=30></a>
20
+ <a href="#"><img src="https://img.shields.io/github/stars/TPCyberSec/json-duplicate-keys" height=30></a>
21
+ <a href="#"><img src="https://img.shields.io/github/forks/TPCyberSec/json-duplicate-keys" height=30></a>
22
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aopen+is%3Aissue"><img src="https://img.shields.io/github/issues/TPCyberSec/json-duplicate-keys" height=30></a>
23
+ <a href="https://github.com/TPCyberSec/json-duplicate-keys/issues?q=is%3Aissue+is%3Aclosed"><img src="https://img.shields.io/github/issues-closed/TPCyberSec/json-duplicate-keys" height=30></a>
44
24
  <br>
45
25
  <a href="#"><img src="https://img.shields.io/pypi/v/json-duplicate-keys" height=30></a>
46
26
  <a href="#"><img src="https://img.shields.io/pypi/pyversions/json-duplicate-keys" height=30></a>
47
27
  <a href="#"><img src="https://img.shields.io/pypi/dm/json-duplicate-keys" height=30></a>
48
28
  </div>
49
29
 
50
- ## Installation
30
+ ---
31
+ # 🛠️ Installation
51
32
  #### From PyPI:
52
33
  ```console
53
34
  pip install json-duplicate-keys
54
35
  ```
55
36
  #### From Source:
56
37
  ```console
57
- git clone https://github.com/tpcybersec/json-duplicate-keys.git --branch <Branch/Tag>
38
+ git clone https://github.com/TPCyberSec/json-duplicate-keys.git --branch <Branch/Tag>
58
39
  cd json-duplicate-keys
59
40
  python -m build
60
41
  python -m pip install dist/json_duplicate_keys-<version>-py3-none-any.whl
61
42
  ```
62
43
 
63
- ## Basic Usage
44
+ ---
45
+ # 📘 Basic Usage
64
46
  ### normalize_key(`name`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
65
47
  _Normalize Key name_
66
48
  - `name`: key name
@@ -73,8 +55,8 @@ import json_duplicate_keys as jdks
73
55
  print(jdks.normalize_key("version{{{_2_}}}"))
74
56
  # OUTPUT: version
75
57
  ```
76
- ---
77
58
 
59
+ ---
78
60
  ### loads(`Jstr`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
79
61
  _Deserialize a JSON format string to a class `JSON_DUPLICATE_KEYS`_
80
62
  - `Jstr`: a JSON format string
@@ -93,8 +75,8 @@ JDKSObject = jdks.loads(Jstr)
93
75
  print(JDKSObject)
94
76
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE987940>
95
77
  ```
96
- ---
97
78
 
79
+ ---
98
80
  ### load(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `skipDuplicated`=False, `_isDebug_`=False)
99
81
  _Deserialize a JSON format string from a file to a class `JSON_DUPLICATE_KEYS`_
100
82
  - `Jfilepath`: The path to the file containing the JSON format string
@@ -115,8 +97,8 @@ JDKSObject = jdks.load(Jfilepath)
115
97
  print(JDKSObject)
116
98
  # OUTPUT: <json_duplicate_keys.JSON_DUPLICATE_KEYS object at 0x00000270AE986D40>
117
99
  ```
118
- ---
119
100
 
101
+ ---
120
102
  ### JSON_DUPLICATE_KEYS.getObject()
121
103
  _Get the JSON object_
122
104
  ```python
@@ -129,8 +111,8 @@ JDKSObject = jdks.loads(Jstr)
129
111
  print(JDKSObject.getObject())
130
112
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
131
113
  ```
132
- ---
133
114
 
115
+ ---
134
116
  ### JSON_DUPLICATE_KEYS.get(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
135
117
  _Get value in the JSON object by `name`_
136
118
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -154,8 +136,8 @@ print(JDKSObject.get("release||$0$"))
154
136
  print(JDKSObject.get("snapshot||author"))
155
137
  # OUTPUT: {'name': 'snapshot||author', 'value': 'truocphan'}
156
138
  ```
157
- ---
158
139
 
140
+ ---
159
141
  ### JSON_DUPLICATE_KEYS.set(`name`, `value`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
160
142
  _Set a new `name` and `value` for the JSON object_
161
143
  - `name`: new key name for the JSON object. Supported flat key name format
@@ -200,8 +182,8 @@ JDKSObject.set("snapshot||author", "truocphan")
200
182
  print(JDKSObject.getObject())
201
183
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan'}}
202
184
  ```
203
- ---
204
185
 
186
+ ---
205
187
  ### JSON_DUPLICATE_KEYS.insert(`name`, `value`, `position`=None, `case_insensitive`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False)
206
188
  _Insert `value` at `position` in value list of `name`_
207
189
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -228,9 +210,19 @@ JDKSObject.insert("snapshot||release", {'version': '2025.1.1'}, 0)
228
210
 
229
211
  print(JDKSObject.getObject())
230
212
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}, {'version': '2025.1.1'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': '2025.1.1'}, {'version': 'latest'}]}}
213
+
214
+
215
+ JDKSObject = jdks.loads("[]")
216
+
217
+ JDKSObject.insert(None, {"release": []})
218
+ JDKSObject.insert(None, {"author": "truocphan"}, 0)
219
+ JDKSObject.insert("$1$||release", {"version": "2025.9.9"})
220
+
221
+ print(JDKSObject.getObject())
222
+ # OUTPUT: [{'author': 'truocphan'}, {'release': [{'version': '2025.9.9'}]}]
231
223
  ```
232
- ---
233
224
 
225
+ ---
234
226
  ### JSON_DUPLICATE_KEYS.update(`name`, `value`, `case_insensitive`=False, `allow_new_key`=False, `separator`="||", `parse_index`="$", `dupSign_start`="{{{", `dupSign_end`="}}}", `ordered_dict`=False, `_isDebug_`=False)
235
227
  _Update new `value` for existing `name` or Set a new `name` in the JSON object_
236
228
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -259,8 +251,8 @@ JDKSObject.update("snapshot||version", "latest")
259
251
  print(JDKSObject.getObject())
260
252
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': ['22.3.3', 'latest'], 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': 'latest', 'release': [{'version': 'latest'}]}}
261
253
  ```
262
- ---
263
254
 
255
+ ---
264
256
  ### JSON_DUPLICATE_KEYS.delete(`name`, `case_insensitive`=False, `separator`="||", `parse_index`="$", `_isDebug_`=False)
265
257
  _Delete a key-value pair in a JSON object by key `name`_
266
258
  - `name`: the key name of the JSON object. Supported flatten key name format
@@ -285,8 +277,8 @@ JDKSObject.delete("snapshot")
285
277
  print(JDKSObject.getObject())
286
278
  # OUTPUT: {'author': 'truocphan', 'version{{{_2_}}}': 'latest', 'release': []}
287
279
  ```
288
- ---
289
280
 
281
+ ---
290
282
  ### JSON_DUPLICATE_KEYS.filter_keys(`name`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
291
283
  _Return a `JSON_DUPLICATE_KEYS` object with keys matching a pattern_
292
284
  - `name`:
@@ -306,8 +298,8 @@ print(JDKSObject.filter_keys("version").dumps())
306
298
  print(JDKSObject.dumps())
307
299
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
308
300
  ```
309
- ---
310
301
 
302
+ ---
311
303
  ### JSON_DUPLICATE_KEYS.filter_values(`value`, `separator`="||", `parse_index`="$", `ordered_dict`=False)
312
304
  _Return a `JSON_DUPLICATE_KEYS` object with values matching a pattern_
313
305
  - `value`:
@@ -327,8 +319,8 @@ print(JDKSObject.filter_values("latest").dumps())
327
319
  print(JDKSObject.dumps())
328
320
  # OUTPUT: {"author": "truocphan", "version": "22.3.3", "version": "latest", "release": [{"version": "latest"}], "snapshot": {"author": "truocphan", "version": "22.3.3", "release": [{"version": "latest"}]}}
329
321
  ```
330
- ---
331
322
 
323
+ ---
332
324
  ### JSON_DUPLICATE_KEYS.dumps(`dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
333
325
  _Serialize a JSON object to a JSON format string_
334
326
  - `dupSign_start`: Start symbol for marking duplicates (default: `{{{`)
@@ -352,8 +344,8 @@ JDKSObject.delete("snapshot")
352
344
  print(JDKSObject.dumps())
353
345
  # OUTPUT: {"author": "truocphan", "version": "latest", "release": []}
354
346
  ```
355
- ---
356
347
 
348
+ ---
357
349
  ### JSON_DUPLICATE_KEYS.dump(`Jfilepath`, `dupSign_start`="{{{", `dupSign_end`="}}}", `_isDebug_`=False, `skipkeys`=False, `ensure_ascii`=True, `check_circular`=True, `allow_nan`=True, `cls`=None, `indent`=None, `separators`=None, `default`=None, `sort_keys`=False)
358
350
  _Serialize a JSON object to a JSON format string and write to a file_
359
351
  - `Jfilepath`: the path to the file to save the JSON format string
@@ -382,8 +374,8 @@ JDKSObject_load = jdks.load(Jfilepath)
382
374
  print(JDKSObject_load.getObject())
383
375
  # OUTPUT: {'author': 'truocphan', 'version': 'latest', 'release': []}
384
376
  ```
385
- ---
386
377
 
378
+ ---
387
379
  ### JSON_DUPLICATE_KEYS.flatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
388
380
  _Flatten a JSON object to a single key-value pairs_
389
381
  - `separator`: Separator for flatten keys (default: `||`)
@@ -405,8 +397,8 @@ JDKSObject.flatten()
405
397
  print(JDKSObject.getObject())
406
398
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release||$0$||version': 'latest', 'snapshot||author': 'truocphan', 'snapshot||version': '22.3.3', 'snapshot||release||$0$||version': 'latest'}
407
399
  ```
408
- ---
409
400
 
401
+ ---
410
402
  ### JSON_DUPLICATE_KEYS.unflatten(`separator`="||", `parse_index`="$", `ordered_dict`=False, `_isDebug_`=False)
411
403
  _Unflatten a flattened JSON object back to a JSON object_
412
404
  - `separator`: Separator for flatten keys (default: `||`)
@@ -428,37 +420,41 @@ JDKSObject.unflatten()
428
420
  print(JDKSObject.getObject())
429
421
  # OUTPUT: {'author': 'truocphan', 'version': '22.3.3', 'version{{{_2_}}}': 'latest', 'release': [{'version': 'latest'}], 'snapshot': {'author': 'truocphan', 'version': '22.3.3', 'release': [{'version': 'latest'}]}}
430
422
  ```
423
+
431
424
  ---
425
+ # 📝 CHANGELOG
426
+ ### [json-duplicate-keys v2025.9.9](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.9.9)
427
+ - **Fixed**: Inserting a value with an `empty` or `null` name
432
428
 
433
- ## CHANGELOG
434
- #### [json-duplicate-keys v2025.8.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.8.19)
435
- - [**Updated**] Add an exception when loading a non-existent file
436
- - [**Updated**] Dump Unicode characters to a file
429
+ ### [json-duplicate-keys v2025.8.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.8.19)
430
+ - **Updated**: Add an exception when loading a non-existent file
431
+ - **Updated**: Dump Unicode characters to a file
437
432
 
438
- #### [json-duplicate-keys v2025.7.1](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.7.1)
439
- - [**Updated**] Fixed some issues when loading JSON strings with `skipDuplicated` option
440
- - [**Updated**] Allow loading of JSON data in byte string format
441
- - [**Updated**] Issue with getting and setting an empty list
433
+ ### [json-duplicate-keys v2025.7.1](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.7.1)
434
+ - **Updated**: Fixed some issues when loading JSON strings with `skipDuplicated` option
435
+ - **Updated**: Allow loading of JSON data in byte string format
436
+ - **Updated**: Issue with getting and setting an empty list
442
437
 
443
- #### [json-duplicate-keys v2025.6.6](https://github.com/tpcybersec/json-duplicate-keys/tree/2025.6.6)
444
- - [**Updated**] Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
438
+ ### [json-duplicate-keys v2025.6.6](https://github.com/TPCyberSec/json-duplicate-keys/tree/2025.6.6)
439
+ - **Updated** Added `skipDuplicated` parameter to `load` and `loads` functions to improve performance when parsing large JSON strings by skipping duplicate keys.
445
440
 
446
- #### [json-duplicate-keys v2024.12.12](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.12.12)
441
+ ### [json-duplicate-keys v2024.12.12](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.12.12)
447
442
  - **New**: _insert_ function
448
443
 
449
- #### [json-duplicate-keys v2024.11.28](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.28)
444
+ ### [json-duplicate-keys v2024.11.28](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.28)
450
445
  - **Fixed**: Add subkey name to empty dict of existing key name
451
446
 
452
- #### [json-duplicate-keys v2024.11.19](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.11.19)
447
+ ### [json-duplicate-keys v2024.11.19](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.11.19)
453
448
  - **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
454
449
 
455
- #### [json-duplicate-keys v2024.7.17](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.7.17)
450
+ ### [json-duplicate-keys v2024.7.17](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.7.17)
456
451
  - **Fixed**: issue #3 break the set function when the key's value is empty. Thanks [ptth222](https://github.com/ptth222) for reporting this issue.
457
452
 
458
- #### [json-duplicate-keys v2024.4.20](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.4.20)
453
+ ### [json-duplicate-keys v2024.4.20](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.4.20)
459
454
  - **New**: _filter_values_
460
455
  - **Updated**: _filter_keys_
461
456
 
462
- #### [json-duplicate-keys v2024.3.24](https://github.com/tpcybersec/json-duplicate-keys/tree/2024.3.24)
457
+ ### [json-duplicate-keys v2024.3.24](https://github.com/TPCyberSec/json-duplicate-keys/tree/2024.3.24)
463
458
  - **Updated**: _normalize_key_, _loads_, _get_, _set_, _update_, _delete_
459
+
464
460
  ---
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "json-duplicate-keys"
7
- version = "2025.8.19"
7
+ version = "2025.9.9"
8
8
  description = "Flatten/ Unflatten and Load(s)/ Dump(s) JSON File/ Object with Duplicate Keys"
9
9
  readme = { file = "README.md", content-type = "text/markdown" }
10
- license = { file = "LICENSE" }
10
+ license = { text = "MIT" }
11
11
  keywords = ["TPCyberSec", "json", "duplicate keys", "json duplicate keys", "flatten", "unflatten"]
12
12
  classifiers = [
13
13
  "Programming Language :: Python :: 3",
@@ -19,7 +19,7 @@ authors = [
19
19
  ]
20
20
 
21
21
  [project.urls]
22
- Homepage = "https://github.com/tpcybersec/json-duplicate-keys"
22
+ Homepage = "https://github.com/TPCyberSec/json-duplicate-keys"
23
23
 
24
24
  [tool.setuptools]
25
25
  packages = ["json_duplicate_keys"]