Parsing Json in Python for root element
Question:
Here is my JSON string which I need to parse.
{
"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"
}
}
Now I want to get value of “id”. I have used jsonpath-rw library for Python, but that is not working. If I use *
whole response gets printed. Looks like the whole response is root. I have used different combinations on http://jsonpath.curiousconcept.com/, such as *.id
, $[0].id
.
Answers:
The following expression is what you need:
$..id
Proof:
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']
However, please be careful, when using ..
operator, since it does deep scan. It means if there is any other object inside your JSON with id
field, value of this field will also be added to result of query.
Your JSON
object contains several root (or top) objects indexed with keys such as "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1"
. From your question it seems you want to access the id
field of these elements. For that the simple way is probably using the json
module – included in the standard library – to load the string and then access the id
of each element.
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))
However if you just want the keys of your JSON
object all you need is
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()])
You don’t have a base/root element – just a collection of keys and values.
You can iterate through them with something like this:
import json
import pprint
values = json.loads(YOUR_JSON_STRING)
for v in values:
print v, pprint.pprint(values[v])
That will print out the following two elements (each with it’s own key) in the resulting JSON object:
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'}}
you can get id
like this(save your json string as a single line file as 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
Found the subject when trying to find a solution for a problem of mine.
In the meantime, I think you found a solution but if anyone is passing by check the jsonlines library that is very useful and could solve the problem
https://jsonlines.readthedocs.io/en/latest/
Here is my JSON string which I need to parse.
{
"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"
}
}
Now I want to get value of “id”. I have used jsonpath-rw library for Python, but that is not working. If I use *
whole response gets printed. Looks like the whole response is root. I have used different combinations on http://jsonpath.curiousconcept.com/, such as *.id
, $[0].id
.
The following expression is what you need:
$..id
Proof:
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']
However, please be careful, when using ..
operator, since it does deep scan. It means if there is any other object inside your JSON with id
field, value of this field will also be added to result of query.
Your JSON
object contains several root (or top) objects indexed with keys such as "192.168.1.2_151b3a32-ce00-114a-e000-0004a50c1c6d_stream1"
. From your question it seems you want to access the id
field of these elements. For that the simple way is probably using the json
module – included in the standard library – to load the string and then access the id
of each element.
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))
However if you just want the keys of your JSON
object all you need is
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()])
You don’t have a base/root element – just a collection of keys and values.
You can iterate through them with something like this:
import json
import pprint
values = json.loads(YOUR_JSON_STRING)
for v in values:
print v, pprint.pprint(values[v])
That will print out the following two elements (each with it’s own key) in the resulting JSON object:
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'}}
you can get id
like this(save your json string as a single line file as 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
Found the subject when trying to find a solution for a problem of mine.
In the meantime, I think you found a solution but if anyone is passing by check the jsonlines library that is very useful and could solve the problem
https://jsonlines.readthedocs.io/en/latest/