How to get nested key value from a json file


How to get nested key value from a json file



I have the following structure:


{
"$schema": "http:",
"title": "al",
"description": "An enitity ",
"id": "a.json#",
"type": "object",
"required": [
"symbol",
"symbolText",
"gene",
"taxonId",
"primaryId"
],
"additionalProperties": false,
"properties": {
"primaryId": {
"$ref": "..",
"description": "The"
},
"symbol": {
"type": "string",
"description": "The symbol of the entity."
},
"symbolText": {
"type": "string",
"description": "the "
},
"taxonId": {
"$ref": "../g",
"description": "The "
},
"synonyms": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"secondaryIds": {
"type": "array",
"items": {
"$ref": "."
},
"uniqueItems": true
},
"gene": {
"$ref": "../globalId.json#/properties/globalId",
"description": "The "
},
"crossReferences": {
"description": "Collection",
"type": "array",
"items": {
"$ref": "../crossReference.json#"
},
"uniqueItems": true
}
}
}



which is saved in a file called "my_keywordfile".
and I want to have something like:


$schema.http,
type.object,
...,
**properties.primaryId.$ref,
properties.primaryId.description**



Here is the code that I have:


json_load = json.load(my_keywordfile)
for key, value in json_load.items():
# print((key,value))
if type(value) == type({}) or type(value) == type():
for x in value:
for i in range(0, len(value) > i):
print(key+'.'+value)



But it gives me this error:


TypeError: must be str, not list



Anyone knows how to fix it? it works fine till this line:


for key, value in json_load.items():
print((key,value))



This section, prints out keys and their values at the first level.
But it seems there is something wrong with the rest of the code!




3 Answers
3


def get_dotted_form(val, old=""):
lines =
if isinstance(val, dict):
for k in val.keys():
lines += get_dotted_form(val[k], old + "." + str(k))
elif isinstance(val, list):
for i,k in enumerate(val):
lines += get_dotted_form(k, old + "." + str(i))
else:
lines += ["{}.{}".format(old,str(val))]

return [line.lstrip('.') for line in lines]

dotted_list = get_dotted_form(json_data)
dotted_string = ',n'.join(s)
print (dotted_string)



Output


$schema.http:,
title.al,
description.An enitity ,
id.a.json#,
type.object,
required.0.symbol,
required.1.symbolText,
required.2.gene,
required.3.taxonId,
required.4.primaryId,
additionalProperties.False,
properties.primaryId.$ref...,
properties.primaryId.description.The,
properties.symbol.type.string,
properties.symbol.description.The symbol of the entity.,
properties.symbolText.type.string,
properties.symbolText.description.the ,
properties.taxonId.$ref.../g,
properties.taxonId.description.The ,
properties.synonyms.type.array,
properties.synonyms.items.type.string,
properties.synonyms.uniqueItems.True,
properties.secondaryIds.type.array,
properties.secondaryIds.items.$ref..,
properties.secondaryIds.uniqueItems.True,
properties.gene.$ref.../globalId.json#/properties/globalId,
properties.gene.description.The ,
properties.crossReferences.description.Collection,
properties.crossReferences.type.array,
properties.crossReferences.items.$ref.../crossReference.json#,
properties.crossReferences.uniqueItems.True





thx. Can you please tell me what does this line mean? lines += get_dotted_form(val[k], old + "." + str(k)) @Sunitha
– nina_dev
Jul 2 at 21:33






Also, this line please: for i,k in enumerate(val): lines += get_dotted_form(k, old + "." + str(i)) @Sunitha
– nina_dev
Jul 2 at 21:39





In lines += get_dotted_form(val[k], old + "." + str(k)) , we are recursively invoking get_dotted_form for any nexted dicts. For eample consider we are parsing properties which is a dict. We are converting it to dotted form and adding the result back to lines. The new prefix we have to add for this dict is old (which would be properties) and adding current element to it. For example for the first element, the new prefix would be properties.primaryId
– Sunitha
Jul 2 at 21:44



lines += get_dotted_form(val[k], old + "." + str(k))


properties


lines


old


properties


properties.primaryId





With for i,k in enumerate(val): lines += get_dotted_form(k, old + "." + str(i)), we apply similar logic for lists. They need to prefixed by the index, which would be obtained by enumerating it. For example, consider the list required; each element has to be prefixed by the index 0,1,2,3,4
– Sunitha
Jul 2 at 21:47


for i,k in enumerate(val): lines += get_dotted_form(k, old + "." + str(i))


required





Thx, @Sunitha. What is the difference between val[k], and str(k). I understand that we are getting the keys of the json data, but why we then have str(k)?
– nina_dev
Jul 2 at 21:49



You need this line to be printing x not value and you can remove the for i in range(0, len(value) > i):


x


value


for i in range(0, len(value) > i):


for x in value:
print(key+'.'+x)





thanks, it worked. But do you know why it does not give me the nested nodes? Now it only give me .... properties.secondaryIds properties.gene properties.crossReferences how can I have properties.genes.description? @Michael Puckett II
– nina_dev
Jul 2 at 20:40






@nina_dev You need to make the loop recursive. Make it test if string then print and if another array then enter the test again. It'll do this downward until it finds the inner most strings and prints them.
– Michael Puckett II
Jul 2 at 20:45



The credit still goes to @Sunitha as I just modified the code to remove the last values, as well as, the index number in case the data is a list.


json_load = json.load(my_keywordfile)
def get_dotted_form(parent,values):
lines =
if isinstance(values,dict):
for key in values.keys():
# print(keys)
lines+=get_dotted_form(parent+"."+key, values[key])
elif isinstance(values,list):
for i,k in enumerate (values):
# print(keys)
lines+=get_dotted_form(parent+"."+k, values[i])
else:
lines.append(parent)
return [line.lstrip('.') for line in lines]

for x in get_dotted_form("",json_load):
print(x)
print('n')






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages