12

I have JSON that looks like this:

{
"ROLE_NAME": {
    "FOO": {
        "download_url": "http: //something.staging/12345/buzz.zip"
    },
    "BAR": {
        "download_url": "http: //something.staging/12345/fizz.zip"
    },
    "download_url": "http: //something.staging/12345/fizzbuzz.zip",
    "db_name": "somedb",
    "db_server": "dbserver.staging.dmz",
    "plugin": {
        "server_url": "http: //lab.staging.corp/server/"
    }
}
}

I wrote a bit of python that replaces the "download_url" k:v with a new value (i.e. new download_url). Unfortunately it only replaces one of the three download_urls in that json snippet. I understand why, but am having a little difficulty getting the solution, and so I am here asking for help.

The entire json object is "data" So I do something like this:

data["ROLE_NAME"]["download_url"] = download_url

Where download_url is a new value I have assigned to that variable What I need to do is for any key called ["download_url"] then update it, rather than the one I have specified at the layer I am going to.

Some of my code to help:

I take some values obtained earlier in my code and build a url which returns a response. I extract a value from the response which will be used to build the value of download_url

buildinfo_url = "http://something.staging/guestAuth/app/rest/builds/?locator=buildType:%s,tags:%s,branch:branched:any" % (
    bt_number,
    list_json_load[role_name][0]['tag']
)

Send HTTP request

client = httplib2.Http()
response, xml = client.request(buildinfo_url)

Extract some value from the response xml and set download_url variable

doc = ElementTree.fromstring(xml)
for id in doc.findall('build'):
    build_id = "%s" % (id.attrib['id'])
try:
    download_url = "http://something.staging/guestAuth/repository/download/%s/%s:id/%s" % (
        bt_number,
        build_id,
        build_artifact_zip
    )
    data[role_name]["download_url"] = download_url
except NameError:
    print "something"

I think I should be recursively searching and updating

Henk Langeveld
  • 8,088
  • 1
  • 43
  • 57
RussellJSmith
  • 381
  • 1
  • 3
  • 8
  • 1
    Please edit the question to include your code so that we can see what is going on. :) – Talvalin Feb 14 '13 at 19:07
  • 1
    Was it this one: http://stackoverflow.com/questions/14048948/how-can-i-use-python-finding-particular-json-value-by-key ? – Jason Sperske Feb 14 '13 at 19:30
  • 1
    Yes, I was just trying to find it again http://stackoverflow.com/questions/14048948/how-can-i-use-python-finding-particular-json-value-by-key -- I think this can be used to help me – RussellJSmith Feb 14 '13 at 19:31

1 Answers1

14

Using recursion

import json   
json_txt = """
{
"ROLE_NAME": {
    "FOO": {
        "download_url": "http: //something.staging/12345/buzz.zip"
    },
    "BAR": {
        "download_url": "http: //something.staging/12345/fizz.zip"
    },
    "download_url": "http: //something.staging/12345/fizzbuzz.zip",
    "db_name": "somedb",
    "db_server": "dbserver.staging.dmz",
    "plugin": {
        "server_url": "http: //lab.staging.corp/server/"
    }
}
}
"""
data = json.loads(json_txt)

def fixup(adict, k, v):
    for key in adict.keys():
        if key == k:
            adict[key] = v
        elif type(adict[key]) is dict:
            fixup(adict[key], k, v)

import pprint
pprint.pprint( data )

fixup(data, 'download_url', 'XXX')

pprint.pprint( data )

Output:

{u'ROLE_NAME': {u'BAR': {u'download_url': u'http: //something.staging/12345/fizz.zip'},
                u'FOO': {u'download_url': u'http: //something.staging/12345/buzz.zip'},
                u'db_name': u'somedb',
                u'db_server': u'dbserver.staging.dmz',
                u'download_url': u'http: //something.staging/12345/fizzbuzz.zip',
                u'plugin': {u'server_url': u'http: //lab.staging.corp/server/'}}}
{u'ROLE_NAME': {u'BAR': {u'download_url': 'XXX'},
                u'FOO': {u'download_url': 'XXX'},
                u'db_name': u'somedb',
                u'db_server': u'dbserver.staging.dmz',
                u'download_url': 'XXX',
                u'plugin': {u'server_url': u'http: //lab.staging.corp/server/'}}}
sotapme
  • 4,695
  • 2
  • 19
  • 20
  • I am testing it out now and will update soon to accept answer - I upvote for the help and quick reply! I love SO {smile} – RussellJSmith Feb 14 '13 at 19:44
  • I came back to say that I was able to use your response to get the desired affect. Thanks @sotapme – RussellJSmith Feb 19 '13 at 17:57
  • Glad to hear it worked - recursion can be dangerous but if you know your data well the it should be OK. Accept the answer if you're happy so others know. – sotapme Feb 19 '13 at 18:25
  • 1
    elif type(json_data[key]) is list: for element in json_data[key]: do stuff; – Jaydev Sep 14 '16 at 16:18