Home > Back-end >  json recursive object update
json recursive object update

Time:08-11

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'}
            }
        }
    }
}
  • Related