我正在尝试验证我们收到的“json”文件,因为生成这些文件的源代码存在一些问题,如果不进行重大修改,这些问题是无法纠正的。“json”中有许多对象是无效的。下面是一个例子,它重用了端口命名的键。
示例无效json文件
[
{"TimeStamp": "2021-11-28", "Address": { "port": "eth2 present", "port": "eth0 present", "port": "eth1 present" }},
{"TimeStamp": "2021-11-29", "CamStatus": 1},
{"TimeStamp": "2021-11-30", "CamDone": 0}
]
我尝试做的是首先确定哪些行是无效的。从那里,如果可能的话,我想清除它们。
使用json.load()
时,我看到了一个奇怪的行为,即解析了无效的json,但排除了两个键/值对。
with open(r"sample.json") as json_file:
content = json.load(json_file)
content
结果
[{'TimeStamp': '2021-11-28', 'Address': {'port': 'eth1 present'}},
{'TimeStamp': '2021-11-29', 'CamStatus': 1},
{'TimeStamp': '2021-11-30', 'CamDone': 0}]
为了识别损坏的行,我使用json.loads()
编写了下面的代码,但是我也得到了意外的行为,即第二个对象被读为无效。
with open("sample.json") as json_file:
for line in json_file:
try:
a = json.loads(line)
print('valid JSON', line)
except:
print('invalid JSON', line)
产出
invalid JSON [
invalid JSON {"TimeStamp": "2021-11-28", "Address": { "port": "eth2 present", "port": "eth0 present", "port": "eth1 present" }},
invalid JSON {"TimeStamp": "2021-11-29", "CamStatus": 1},
valid JSON {"TimeStamp": "2021-11-30", "CamDone": 0}
invalid JSON ]
我尝试做的是生成一个如下结构:
[{'TimeStamp': '2021-11-28', 'Address': {'port0': 'eth1 present', 'port1': 'eth2 present', 'port2': 'eth3 present'}},
{'TimeStamp': '2021-11-29', 'CamStatus': 1},
{'TimeStamp': '2021-11-30', 'CamDone': 0}]
有什么想法、模块、示例代码可以帮助我吗?
1条答案
按热度按时间hgc7kmma1#
可以给JSON解析器一个参数,告诉它在收集由键/值对组成的对象时使用标准
dict
以外的对象。如果在该参数中提供multidict
构造函数,那么最终得到的结构将保留原始JSON文件中的所有信息,即使该文件包含重复的键(因此是无效的JSON)。完成此操作后,就可以查询数据结构,以查找内部MultiDict对象之一中存在多个同名键的位置,并标记出现这种情况的行。
下面是一个简单的例子,它可以针对您所展示的数据执行此操作。我预计它需要针对实际情况进行修改,但它演示了以这种方式使用JSON解析器,然后在结果中标记无效的键/值对结构的基本思想:
结果:
您可以遍历结果结构并构建一个新的结构,当遇到重复键时,您可以在其中处理它们,从而"修复"传入的数据结构。您可以将键重命名为(在本例中)
port1
、port2
等,或者您可以将这种情况下的值收集到列表中。然后可以使用json.dump
写出该结构,以生成有效的JSON文件。下面的代码采用前一种方法将读结构转换回只包含普通
dict
对象的结构。注意,新键名中的下划线是必要的,以避免与现有名称冲突。这是可以避免的。但逻辑必须稍微复杂一点,以允许与结尾为数字的现有键名发生冲突。是好的演示,因为它清楚地表明哪些键被重命名。结果:
下面是使用第二种方法的代码:
结果: