Home > database >  Find Nested Json Path with key using python
Find Nested Json Path with key using python

Time:07-30

I am trying to find all the full path for specific key. I tried with recursion, i can able to get the values, but i can't able to track the path using my code. Any Help will definitely useful for me.

Input:

{
  "id": ["0001"],
  "type": "donut",
  "name": "Cake",
  "ppu": 0.55,
  "batters": {
    "batter": {
      "id": ["1001"],
      "type": "Regular"
    }
  },
  "topping": [
    {
      "id": ["5001"],
      "type": "None"
    },
    {
      "id": ["5002"],
      "type": "Glazed"
    }
  ]
}

Expected Output:

[
    {"id":["0001"]},
    {"batters.batter.id":["1001"]},
    {"topping[0].id":["5001"]},
    {"topping[0].id":["5002"]}
]

Following code is i have used for get the values, but it doesn't helped me.

def json_extract(obj, key):
    """Recursively fetch values from nested JSON."""
    arr = []

    def extract(obj, arr, key):

        """Recursively search for values of key in JSON tree."""
        if isinstance(obj, dict):
            for k, v in obj.items():
                if isinstance(v, (dict)):
                    extract(v, arr, key)
                elif k == key:
                    arr.append(v)
        elif isinstance(obj, list):
            for item in obj:
                extract(item, arr, key)
        return arr

    values = extract(obj, arr, key)
    return values

CodePudding user response:

You can use this code to acheive the same (not optimized though).

import json
# Opening JSON file
f = open('del.json')
data = json.load(f)
arr = []
def json_extract(obj, key):
    def dfs(obj, key, prefix):
        for k, v in obj.items():
            if(isinstance(v, dict)):
                if(k == key):
                    arr.append((prefix "." k if prefix else k, v))
                else:
                    dfs(v, key, prefix   "."   k if prefix else k)
            elif(isinstance(v, list)):
                if(k == key):
                    arr.append((prefix "." k if prefix else k, v))
                else:
                    for i, val in enumerate(v):
                        dfs(val, key, prefix   k   f"[{i}]")
  
    dfs(obj, key, "")
    
json_extract(data, "id")
for i in arr:
    print(i)

CodePudding user response:

Thanks for providing solution Olvin Right.

def get_paths(source, key="", target = None):
    if isinstance(source, dict):
        for source_key, source_value in source.items():
            tmp_key = f"{key}.{source_key}" if key else source_key
            if source_key == target:
                yield tmp_key, source_value, source.get('_type')
            else:
                yield from get_paths(source_value, tmp_key, target)
    elif isinstance(source, (list, tuple, set, frozenset)):
        for index, value in enumerate(source):
            yield from get_paths(value, f"{key}[{index}]", target)
  • Related