0

I am somewhat limited by my knowledge of the json library, but i cannot find a way to access the branches of the file anywhere. I`ll form the question using a JSON example file as found in http://json.org/example.html

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

i have done the following. Written a preprocess function:

def PreProc(JSONFile):
    with open(JSONFile, 'r') as myfile:
        data = myfile.read()
    myfile.close()
    return data

And called it:

path = 'C:\\path\\file.json'
Data = json.loads(PreProc(path))

At this point:

print(type(Data.keys()))
print(Data.items())
print(type(Data.items()))

returns:

<class 'dict_keys'>
dict_items([('glossary', {'title': 'example glossary', 'GlossDiv': .......
<class 'dict_items'>

How do i access any branch or subbranch of the JSON file by keyword and return it in either a string or a dictionary format?
My actual JSON file contains list of complex objects that also have lists of objects in them and that is why i would rather do it like this, and avoid an overly complex object representation and JSONDecoders and object hooks which i just cannot wrap my head around. I am looking for a solution that would work somewhat like this conceptual function:

def Recursion(Dict,Structure):
    #Attempts to find a keyword that marks the begging of a complex ctructure in a given dictionary
    try:
        for key in Dict.keys():
            #Parses through all the keys of the dictionary
            try:
                if key==Structure:
                    NewDict = key.items()
                    return NewDict
                else:
                    #Set the dictionary that will be used in the recursion as all the items in the 'key' branch
                    dict = key.items()
                Recursion(dict, Structure)
            except:
                continue
    except:
        print("Needed Structure Not Found in Dictionary ", Dict, " !") 

The call of the function throws and AttributeError because in the first recursive step it tries to parse dict_items as a dict. Ideally, the statements:

BranchedData = Recursion(Data,'GlossList')  
print(BranchedData)

Should output (as a string or a dict):

{
    "GlossEntry": {
    "ID": "SGML",
    "SortAs": "SGML",
    "GlossTerm": "Standard Generalized Markup Language",
    "Acronym": "SGML",
    "Abbrev": "ISO 8879:1986",
    "GlossDef": {
        "para": "A meta-markup language, used to create markup languages such as DocBook.",
        "GlossSeeAlso": ["GML", "XML"]
    },
    "GlossSee": "markup"
    }
}  

Edit: clarified the question and adjust the code for clarity and dumb mistake

  • 2
    You don't need to use `myfile.close()` when you open it with `with`, it automatically closes it for you. – Barmar Jan 12 '18 at 23:33
  • You need to return the value of the recursive call: `return Recursion(dict, Structure)`. – Barmar Jan 12 '18 at 23:36
  • Possible duplicate of [Recursive function does not return specified value](https://stackoverflow.com/questions/27691547/recursive-function-does-not-return-specified-value) – Barmar Jan 12 '18 at 23:36
  • The function `Recursion(dict, Structure)` has more of a conceptual nature since it does throw `AttributeError` in its current state. I was more interested in how i could slice the dictionary or the string to get only the "branches" of the JSON file that are marked with the keyword `Structure` – Oskars Sjomkāns Jan 13 '18 at 00:09
  • Are you asking how to collect multiple branches in the result, if `GlossList` appears repeatedly? – Barmar Jan 13 '18 at 00:11
  • No, just the one. Everything that is a child to `GlossList` i need outputted as a string or a dictionary, does not matter which. – Oskars Sjomkāns Jan 13 '18 at 00:21
  • Isn't that what your function does if you fix the error? – Barmar Jan 13 '18 at 00:21
  • I have no idea how to change the `dict_items` to `dict` which is the core of the problem with the `Recursion`function, but i gave a lot of context to maybe find other ways to do this if it cannot be done. – Oskars Sjomkāns Jan 13 '18 at 00:35
  • See https://stackoverflow.com/questions/9807634/find-all-occurrences-of-a-key-in-nested-python-dictionaries-and-lists/20254898#20254898 – Barmar Jan 13 '18 at 00:40

0 Answers0