Reputation: 363
My test url returns below json response: a={ "version": "1.3.0", "services": [ { "version": "1.0.0", "serviceGun": "com.xx.version.1", "description": "test service", "links": [ { "rel": "capabilities", "href": "/abc/test", "hints": [ { "method": "get" } ]
},
{
"version": "1.0.0",
"serviceGun": "com.xx.abx.version.1",
"description": "mode",
"links": [
{
"rel": "mediaConfiguration",
"href": "/abc/rest",
"hints": [
{
"method": "get"
},
{
"method": "put"
} ]
},
{
"rel": "modeConfiguration",
"href": "/abc/mode",
"hints": [
{
"method": "get"
},
{
"method": "put"
} ]
},
{
"version": "1.0.0",
"serviceGun": "com.xx.abc.version.1",
"description": "controlPanel",
"links": [
{
"rel": "configuration",
"href": "/abc/controlPanel",
"hints": [
{
"method": "get"
},
{
"method": "put"
} ]
},
{
"rel": "state",
"href": "/abc/awc",
"state": "unavailable",
"stateReason": "inactivated",
"hints": [
{
"method": "get"
} ]
} ]
},
]
}
With below function I am able to retrieve single value from json (e.g href,rel etc). But I want the function to return a list which has all "href" with supporting methods in "hints" for each href. e.g : [(href1,hints1),(href1,hints1),(href1,hints1)]
Expected output : [('/abc/test',['get','put']),('/abc/rest',['get','put']),...]
def extract_values(obj, key): """Pull all values of specified key from nested JSON.""" arr = []
def extract(obj, arr, key):
"""Recursively search for values of key in JSON tree."""
if isinstance(obj, dict):
for k, v in obj.items():
if isinstance(v, (dict, list)):
extract(v, arr, key)
elif k == key:
arr.append(v)
elif isinstance(obj, list):
for item in obj:
extract(item, arr, key)
return arr
results = extract(obj, arr, key)
return results
Run : test_ref = extract_values(a,'href') print test_ref Output : ['/abc/test','/abc/rest',','/abc/mode','/abc/controlPanel','abc/awc']
Expected Output : [('/abc/test',['get','put']),('/abc/rest',['get','put']),...]
Upvotes: 0
Views: 216
Reputation: 1196
I think your recursion tries to solve a problem that does not exist. Your JSON has a hierarchical structure that is clearly visible.
a['services']
is a list of servicesa['services'][i]['links']
is the list of links of i
th servicea['services'][i]['links'][j]['href']
is the URL of the j
th link of the i
th serviceSo my function would look like this:
def parse_links_and_methods(json_result):
for service in json_result['services']:
for link in service['links']:
for hint in link['hints']:
if 'method' in hint:
yield link['href'], hint['method']
This is basically just one huge list comprehension. You would use it as:
print list(parse_links_and_methods(a))
and get [('/abc/test', 'get'), ('/abc/rest', 'get'), ('/abc/rest', 'put'), ('/abc/mode', 'get'), ('/abc/mode', 'put'), ...]
EDIT I misread your expected output. To have it the way you want it use
def parse_links_and_methods(json_result):
for service in json_result['services']:
for link in service['links']:
methods = [hint['method'] for hint in link['hints']
if 'method' in hint]
yield link['href'], methods
Upvotes: 1