【问题标题】:How to parse a JSON string with no root element?如何解析没有根元素的 JSON 字符串?
【发布时间】:2019-04-24 21:28:07
【问题描述】:

我有一个如下的 JSON 文件:

{
  "name":"A",
  "age":19
}
{
  "name":"B",
  "age":20
}

所以基本上该文件包含人员列表。

我尝试在 Python 3 中使用json.loads(str_content),但它返回了json.decoder.JSONDecodeError: Extra data: 的错误。

我检查了一个在线 JSON 解析器 (http://json.parser.online.fr),它告诉我同样的问题。

如何解析没有根元素但有 JSON 对象列表的 JSON 文件?

【问题讨论】:

  • age:20有语法错误
  • 问题是你没有有一个JSON文件;是什么创建了该文件,是否可以将其修改为具有单个根数组?
  • @Chirag 谢谢,我修改了。
  • @jonrsharpe 我认为该文件是从 MongoDB 创建的。事实上,我是一个 BSON 文件,然后我将它转换为 JSON。
  • 是否存储在多行json中?像这样{"name":"A","age":19} {"name":"B","age":20}每个换行

标签: python json python-3.x


【解决方案1】:

问题是您尝试解析的字符串不是有效的 JSON 文档。它实际上是 JSON 文档的串联。所以简单的json.loads() 是行不通的。

您可以改用基于 https://docs.python.org/3/library/json.html#json.JSONDecoder.raw_decode 的东西。例如:(代码有点丑,但逻辑应该清楚):

import json

s = """{
  "name":"A",
  "age":19
}
{
  "name":"B",
  "age":20
}"""

def iter_jsons(s):
    decoder = json.JSONDecoder()

    i = 0
    while True:
        doc, i2 = decoder.raw_decode(s[i:].strip())
        yield doc
        if i == i2:
            break
        i= i2

print(list(iter_jsons(s)))

[{'name': 'A', 'age': 19}, {'name': 'B', 'age': 20}]

【讨论】:

  • 如果没有嵌套的字典,您可以简单地查找右大括号并解析到该点。
  • 我在 json 标准中找不到任何表明 JSON 文档必须具有根元素的内容。
  • @TomasZubiri 在tools.ietf.org/html/rfc7159#section-2 中没有明确表示为文本,但 ABNF 表明 JSON 文本是一个单一值
  • @TomasZubiri:我相信标准表明 JSON 文档必须是包含在 {} 括号中的单个 JSON 对象,或者是包含在 [ 中的逗号分隔列表, ] 括号。这个答案看起来是一个非常聪明的解决方法,允许将这个不合规的输入解码到它本来应该放在首位的列表中。
  • @tripleee:这是正确的,但我宁愿不对我要解析的内容做出任何假设。
【解决方案2】:

这就像一个魅力

import json        
json_file = "myfile.json"

objects = json.load(open(json_file))

for person in objects:
    name = person['name']
    print(name)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2019-10-13
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 2011-10-02
    相关资源
    最近更新 更多