【问题标题】:Parsing Json in Python for root element在 Python 中解析 Json 以获取根元素
【发布时间】:2015-01-27 10:53:01
【问题描述】:

这是我需要解析的 JSON 字符串。

{
  "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1" : {
    "@class" : "com.barco.compose.media.transcode.internal.h264.H264Gateway",
    "id" : "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1",
    "uri" : {
      "high" : "rtp://239.1.1.2:5006",
      "low" : "rtp://239.1.1.1:5006"
    },
    "owner" : {
      "@class" : "com.barco.compose.media.transcode.Acma",
      "source" : "dvi1-1-mna-1890322558",
      "stream" : "udp://239.1.1.7:5004",
      "type" : "video",
      "resolution" : [ 1, 1 ],
      "framerateDivider" : [ 1, 1 ],
      "profile" : [ "baseline" ],
      "output" : [ "high", "low" ],
      "destination" : [ "", "" ],
      "ipvsProfile" : "high",
      "ipvsSDP" : [ "" ],
      "ipvsTitle" : "DiORStream",
      "ipvsTagName" : [ "" ],
      "ipvsTagValue" : [ "" ],
      "ipvsDescription" : "NMSDesc",
      "ipvsHLS" : true
    },
    "type" : "video"
  },
  "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream2" : {
    "@class" : "com.barco.compose.media.transcode.internal.h264.H264Gateway",
    "id" : "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream2",
    "uri" : {
      "high" : "rtp://239.1.1.4:5006",
      "low" : "rtp://239.1.1.3:5006"
    },
    "owner" : {
      "@class" : "com.barco.compose.media.transcode.Acma",
      "source" : "dvi1-1-mna-1890322558",
      "stream" : "udp://239.1.1.7:5004",
      "type" : "video",
      "resolution" : [ 1, 1 ],
      "framerateDivider" : [ 1, 1 ],
      "profile" : [ "baseline" ],
      "output" : [ "high", "low" ],
      "destination" : [ "", "" ],
      "ipvsProfile" : "high",
      "ipvsSDP" : [ "" ],
      "ipvsTitle" : "nikhil",
      "ipvsTagName" : [ "" ],
      "ipvsTagValue" : [ "" ],
      "ipvsDescription" : "nikhilDesc",
      "ipvsHLS" : true
    },
    "type" : "video"
  }
}

现在我想获得“id”的值。我已经将jsonpath-rw library 用于Python,但这不起作用。如果我使用*,整个响应就会被打印出来。看起来整个响应是根。我在http://jsonpath.curiousconcept.com/上使用了不同的组合,比如*.id,$[0].id。

【问题讨论】:

  • 您似乎没有根 id 元素,只有子元素中的 id。

标签: python json python-3.x


【解决方案1】:

您的JSON 对象包含多个使用"192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1" 等键索引的根(或顶部)对象。从您的问题来看,您似乎想访问这些元素的 id 字段。为此,简单的方法可能是使用标准库中包含的json 模块来加载字符串,然后访问每个元素的id。

import json
my_json_string = "..."
my_json_dict = json.loads(my_json_string)
for key, value in my_json_dict.items():
    print("Id is {} for item {}".format(value["id"], key))

但是,如果您只想要 JSON 对象的键,您只需要

import json
my_json_string = "..."
my_json_dict = json.loads(my_json_string)
print(["Got item with id '{}'".format(key) for key in d.keys()])

【讨论】:

  • 我怎样才能得到一个“id”,使用上面的代码给了我两个id,这很好,但我怎么能一次只有一个值。
  • d.keys() 返回一个类似列表的对象,该对象支持成员资格测试和迭代等操作,因此如果您想使用以下代码访问任何元素:d.keys()[1] 以获取第一个“id”跨度>
【解决方案2】:

您没有基本/根元素 - 只是键和值的集合。

你可以用这样的方式遍历它们:

import json
import pprint

values = json.loads(YOUR_JSON_STRING)

for v in values:
    print v, pprint.pprint(values[v])

这将在生成的 JSON 对象中打印出以下两个元素(每个元素都有自己的键):

192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1{u'@class': u'com.barco.compose.media.transcode.internal.h264.H264Gateway',
 u'id': u'192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1',
 u'owner': {u'@class': u'com.barco.compose.media.transcode.Acma',
            u'destination': [u'', u''],
            u'framerateDivider': [1, 1],
            u'ipvsDescription': u'NMSDesc',
            u'ipvsHLS': True,
            u'ipvsProfile': u'high',
            u'ipvsSDP': [u''],
            u'ipvsTagName': [u''],
            u'ipvsTagValue': [u''],
            u'ipvsTitle': u'DiORStream',
            u'output': [u'high', u'low'],
            u'profile': [u'baseline'],
            u'resolution': [1, 1],
            u'source': u'dvi1-1-mna-1890322558',
            u'stream': u'udp://239.1.1.7:5004',
            u'type': u'video'},
 u'type': u'video',
 u'uri': {u'high': u'rtp://239.1.1.2:5006', u'low': u'rtp://239.1.1.1:5006'}}
 None
192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream2{u'@class': u'com.barco.compose.media.transcode.internal.h264.H264Gateway',
 u'id': u'192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream2',
 u'owner': {u'@class': u'com.barco.compose.media.transcode.Acma',
            u'destination': [u'', u''],
            u'framerateDivider': [1, 1],
            u'ipvsDescription': u'nikhilDesc',
            u'ipvsHLS': True,
            u'ipvsProfile': u'high',
            u'ipvsSDP': [u''],
            u'ipvsTagName': [u''],
            u'ipvsTagValue': [u''],
            u'ipvsTitle': u'nikhil',
            u'output': [u'high', u'low'],
            u'profile': [u'baseline'],
            u'resolution': [1, 1],
            u'source': u'dvi1-1-mna-1890322558',
            u'stream': u'udp://239.1.1.7:5004',
            u'type': u'video'},
 u'type': u'video',
 u'uri': {u'high': u'rtp://239.1.1.4:5006', u'low': u'rtp://239.1.1.3:5006'}}

【讨论】:

    【解决方案3】:

    下面的表达式是你需要的:

    $..id
    

    证明:

    In [12]: vv = json.loads(my_input_string)
    
    In [13]: jsonpath_expr = parse('$..id')
    
    In [14]: [x.value for x in jsonpath_expr.find(vv)]
    Out[14]: 
    [u'192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1',
     u'192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream2']
    

    但是,请小心,在使用 .. 运算符时,因为它会进行深度扫描。这意味着如果您的 JSON 中有任何其他带有 id 字段的对象,该字段的值也将添加到查询结果中。

    【讨论】:

    • 我试过了,但我一次想要一个值,不知道实用程序 JSON_PATH RW 有多大用处
    【解决方案4】:

    你可以像这样得到id(将你的json字符串保存为单行文件为test.json):

    import simplejson as json
    
    with open("test.json") as fp:
        line = fp.readline()
        json = json.loads(line)
        for k,v in json.items():
            print v.get("id","no id found") # no id found is the default value in case there is no id defined
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 2018-10-07
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多