0

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']),...]

1 Answer 1

1

I think your recursion tries to solve a problem that does not exist. Your JSON has a hierarchical structure that is clearly visible.

  1. a['services'] is a list of services
  2. a['services'][i]['links'] is the list of links of ith service
  3. a['services'][i]['links'][j]['href'] is the URL of the jth link of the ith service

So 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
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Karl, both the methods suggested by you above work perfectly. Learned a new concept of Generators from your solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.