将JSON文件中的值替换为可以嵌套n个级别的密钥 [英] Replace value in JSON file for key which can be nested by n levels
问题描述
我有一个看起来像这样的JSON:
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/"
}
}
}
我写了一些python,将"download_url" k:v替换为新值(即新的download_url).不幸的是,它仅替换了该json代码段中的三个download_urls之一.我知道为什么,但是在获得解决方案方面有些困难,因此我在这里寻求帮助.
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.
整个json对象是数据" 所以我做这样的事情:
The entire json object is "data" So I do something like this:
data["ROLE_NAME"]["download_url"] = download_url
在哪里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:
我采用了我的代码中较早获得的一些值,并构建了一个返回响应的URL.我从响应中提取一个值,该值将用于构建download_url
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']
)
发送HTTP请求
client = httplib2.Http()
response, xml = client.request(buildinfo_url)
从响应xml中提取一些值并设置download_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
推荐答案
使用递归
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 )
输出:
{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/'}}}
这篇关于将JSON文件中的值替换为可以嵌套n个级别的密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!