Reputation: 1691
Using python on web2py server I have following problem. How do I loop trough json to find all the keys that have null values (or empty strings) and collect those keys to report what is missing:
This is my json example.
{
"version" : 1,
"general" : {
"scriptFrom" : "",
"scriptTo" : "1.1.2014",
"scriptComment" : "dada"
},
"nbworkersDays" : [{
"days" : ["1", "2"],
"data" : [{
"nbWorkersFrom" : 2,
"nbWorkersTo" : null,
"timeFrom" : "12:00",
"timeTo" : ""
}
,{
"nbWorkersFrom" : 2,
"nbWorkersTo" : 7,
"timeFrom" : "9:00",
"timeTo" : "14:00"
}
]
}
]}
I was thinking to retrieve a list with all keys and if nested than first level . second level. missingData= [scriptFrom, nbworkersDays.nbWorkersTo, nbworkersDays.timeTo]
any suggestions on how to solve this or how would you collect all the errors to report back to client (I have a web app using web2py) thank you
Upvotes: 0
Views: 1437
Reputation: 31339
You can use a recursive function to iterate over the values of complex objects while remembering the path you're at (to report back):
#!/usr/bin/env python
# used to parse the json text
import json
with open('json.txt', 'r') as f:
d = json.load(f)
# define list of what your consider as "missing"
missings = [None, ""]
# recursive function to collect missing paths and alter the aggregator list
# make sure to add cases if needed
def aggregate_missing_paths(aggregator, path, item):
if isinstance(item, list):
# check all list items
map(lambda x: aggregate_missing_paths(aggregator, path, x), item)
if isinstance(item, dict):
# check all dict items
map(lambda kv: aggregate_missing_paths(aggregator, path + '.' + kv[0], kv[1]), item.iteritems())
if item in missings:
# alter list to cotain path to missing
aggregator.append(path)
aggregator = []
aggregate_missing_paths(aggregator, 'root', d)
print aggregator
I added a version without the aggregator using a recursive generator:
#!/usr/bin/env python
import json
with open('json.txt', 'r') as f:
d = json.load(f)
missings = [None, ""]
def generate_missing_paths(path, item):
if isinstance(item, list):
for v in item:
for current_path in generate_missing_paths(path, v):
yield current_path
if isinstance(item, dict):
for k, v in item.iteritems():
for current_path in generate_missing_paths(path + '.' + k, v):
yield current_path
if item in missings:
yield path
for path in generate_missing_paths('root', d):
print path
Upvotes: 2