I'm working on a json schema parsing script. Since I don't know what kind of json schema I can expect, meaning how many nesting levels I've taking a look into recursive data manipulation. After some research I've come up with the following:
import json
import pandas as pd
jsonString = '{"transportation": {"airplane": {}, "car": {}, "boat": {}}}'
jsonObj = json.loads(jsonString)
dataObj = ['airplane','car','boat']
dataProp = ['airplane','fly'],['car','drive'],['boat','sail'],['airplane','pilot'],['car','driver'],['boat','sailer']
dfObj = pd.DataFrame(dataObj, columns=['object'])
dfProp = pd.DataFrame(dataProp, columns=['object','property'])
#updating nested JSON
def update_panel_json(input_json, target_key, update_value):
if type(input_json) is dict and input_json:
for key in input_json:
if key == target_key:
input_json[key] = update_value
update_panel_json(input_json[key], target_key, update_value)
elif type(input_json) is list and input_json:
for entity in input_json:
update_panel_json(entity, target_key, update_value)
#add properties object to JSON
for index, row in dfProp.iterrows():
properties = { "properties": { row['property']: {"type":"string"} }}
target = row['object']
update_panel_json(jsonObj, target, properties)
print(jsonObj)
This works pretty well for the underlying objects.
Output:
{'transportation': {'airplane': {'properties': {'pilot': {'type': 'string'}}}, 'car': {'properties': {'driver': {'type': 'string'}}}, 'boat': {'properties': {'sailer': {'type': 'string'}}}}}
However once the root object also has properties the json objects seems to be overwritten only containing the root object with the last property.
Input:
dataProp = ['transportation','someproperty'],['airplane','fly'],['car','drive'],['boat','sail'],['airplane','pilot'],['car','driver'],['boat','sailer']
Output:
{'transportation': {'properties': {'someproperty': {'type': 'string'}}}}
I don't see what I'm doing wrong. Can someone help out?
CodePudding user response:
I've cleaned it up a bit for easy debugging. I hope it'll give you an idea of how you can handle it:
dataProp = (
['airplane', 'fly'],
['car', 'drive'],
['boat', 'sail'],
['airplane', 'pilot'],
['car', 'driver'],
['boat', 'sailer']
)
obj = {'transportation': {'airplane': {}, 'car': {}, 'boat': {}}}
def update_panel_json(obj, target_key, update_value):
if isinstance(obj, dict):
for key, value in obj.items():
if key == target_key:
obj[key].setdefault('properties', {}).update(update_value)
update_panel_json(value, target_key, update_value)
elif isinstance(obj, list):
for entity in obj:
update_panel_json(entity, target_key, update_value)
for key, prop in dataProp:
new_prop = {prop: {"type": "string"}}
update_panel_json(obj, key, new_prop)
Output:
{
'transportation': {
'airplane': {
'properties': {
'fly': {'type': 'string'},
'pilot': {'type': 'string'}
}
},
'boat': {
'properties': {
'sail': {'type': 'string'},
'sailer': {'type': 'string'}
}
},
'car': {
'properties': {
'drive': {'type': 'string'},
'driver': {'type': 'string'}
}
}
}
}