1

Hello everyone, I have a json text below

data = {
"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...",
                    "GlossSeeAlso": ["GML", "XML"]
                },
                "GlossSee": "markup"
            }
        }
    }
}

}

I created a function that can get the path to all fields of json. like below:

def get_paths(source):
paths = []
if isinstance(source, collections.MutableMapping):  # found a dict-like structure...
    for k, v in source.items():  # iterate over it; Python 2.x: source.iteritems()
        paths.append([k])  # add the current child path
        paths += [[k] + x for x in get_paths(v)]  # get sub-paths, extend with the current
# else, check if a list-like structure, remove if you don't want list paths included
elif isinstance(source, collections.Sequence) and not isinstance(source, str):
    #                          Python 2.x: use basestring instead of str ^
    for i, v in enumerate(source):
        paths.append([i])
        paths += [[i] + x for x in get_paths(v)]  # get sub-paths, extend with the current
return paths

now you can see all path like below:

[['glossary'],
['glossary', 'title'],
['glossary', 'GlossDiv'],
['glossary', 'GlossDiv', 'title'],
['glossary', 'GlossDiv', 'GlossList'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'ID'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'SortAs'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossTerm'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'Acronym'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'Abbrev'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'para'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso'],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso', 0],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossDef', 'GlossSeeAlso', 1],
['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'GlossSee']]

How to traverse the path list to get the value of each field of json?

andylei
  • 53
  • 2
  • There is a `json` built-in library, you can load a json from a file or string variable using `json.loads()`. See the [reference here](https://docs.python.org/3/library/json.html) –  Jun 13 '19 at 13:42

2 Answers2

3

Python provides the json module, which can read a JSON file into a python dict data structure:

import json

with open("my_file.json", "r") as my_file:
    contents = json.loads(my_file.read())

After which, you can treat it as a dict:

title = contents["glossary"]["title"]
glossDivTitle = contents["glossary"]["glossDiv"]["title"]
para = contents["glossary"]["glossDiv"]["glossList"]["glossEntry"]["glossDef"]["para"]
...

Now, let's say you have a list like this, which you created in your question:

lk = ['glossary', 'GlossDiv', 'GlossList', 'GlossEntry', 'Acronym']

Here's a function that you could use to retrieve the relevant value:

def retrieve_value(key_list, dct):
    subdict = dct
    for k in key_list:
        subdict = subdict[k]
    return subdict

retrieve_value(lk, contents)
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • 1
    If you're opening a physical file probably simpler to use `contents = json.load(my_file)` instead.. but same result. – Zhenhir Jun 13 '19 at 13:47
  • hi thanks for you comment, but some thing not i wanted ,current issue its i get json field path title A = ['glossary', 'GlossDiv', 'title'] how can i get tiltle from data[A[0]][A[1]][A[2]]? – andylei Jun 13 '19 at 14:08
  • @andylei I've edited my answer to include a section on how you could get the information from the lists you included at the bottom of your question – Green Cloak Guy Jun 13 '19 at 14:12
  • hi Green Cloak Guy, brother i find you anwser thanks a lot :) – andylei Jun 13 '19 at 14:20
  • hi brother if i use lk path to update content how to do it ? example use lk update content set only Acronym value changed? – andylei Jun 13 '19 at 14:39
  • You can update the dict by doing `dict[key] = value`. This should be a straightforward modification of the `retrieve_value()` function I made - I'll leave it as an exercise for the reader. You can then use `json.dumps(dict)` to produce a JSON string from the now-modified dict, and then save that back to a file. – Green Cloak Guy Jun 13 '19 at 14:41
  • hi Green Cloak Guy you can see my another question https://stackoverflow.com/q/56589613/11581583 – andylei Jun 13 '19 at 23:24
1

I recommend you to use the json library. https://www.w3schools.com/python/python_json.asp You cane use json.loads that will transform the json into a dict and you can access a value by dict_name[key]

Try to find a library before writing a function.

Simone
  • 78
  • 1
  • 6
  • Hi simone thanks for you comment my error for the question not clear , current issue its i get json field path title A = ['glossary', 'GlossDiv', 'title'] how can i get tiltle value from data[A[0]][A[1]][A[2]]? – andylei Jun 13 '19 at 14:09