1

I have the following Json:

 { 
   file1: {
     path_to_file: 'file1.txt',
     children : 'file2'
   },
   file2: {
     path_to_file: 'file1.txt',
     children : 'file3,file4'
   },
   file3: {
     path_to_file: 'a/file3.txt',
     children : ''
   },
   file4: {
     path_to_file: 'b/file4.txt',
     children : ''
   }
 }

I want to construct a tree from this Json. each node should have: name (file1 etc..), path_to_file which is just a data field and convert the children into "pointers" to next node.

I have the following code:

class Node(object):
    def __init__(self, name, path_to_file=None):
        self.name = name
        self.path_to_file= path_to_file
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)

This can be used as:

>>> n = Node(5)
>>> p = Node(6)
>>> q = Node(7)
>>> n.add_child(p)
>>> n.add_child(q)

Now, I want to use properties from my json instead of the number above. So I have this code:

jsonObject= json.load(json_string)
for key in jsonObject:
   value = jsonObject[key]
   print("The key and value are ({}) = ({})".format(key, value))

This gives me:

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 4 (char 7)

How can I extract the properties in the Json object inorder to construct the call to the Node class?

2
  • You get an error because json_string is likely an invalid JSON. Otherwise, our code looks ok-ish. Also, for key, value in jsonObject.items(): is more idiomatic. Commented Apr 3, 2019 at 7:45
  • @MartinIndra When I copy paste this Json example to jsoneditoronline.org it parse it ok. Commented Apr 3, 2019 at 7:47

1 Answer 1

2

Your json is not a standard json format, it should be double quotes, no single quotes

import json

json_string = """
{
    "file1": {
        "path_to_file": "file1.txt",
        "children": "file2"
    },
    "file2": {
        "path_to_file": "file1.txt",
        "children": "file3,file4"
    },
    "file3": {
        "path_to_file": "a/file3.txt",
        "children": ""
    },
    "file4": {
        "path_to_file": "b/file4.txt",
        "children": ""
    }
}
"""

jsonObject = json.loads(json_string)
for key in jsonObject:
   value = jsonObject[key]
   print("The key and value are ({}) = ({})".format(key, value))

output as:

The key and value are (file1) = ({'path_to_file': 'file1.txt', 'children': 'file2'})
The key and value are (file2) = ({'path_to_file': 'file1.txt', 'children': 'file3,file4'})
The key and value are (file3) = ({'path_to_file': 'a/file3.txt', 'children': ''})
The key and value are (file4) = ({'path_to_file': 'b/file4.txt', 'children': ''})

update answer

For better display, I added the dump method.

import json
json_string = """
{
    "file1": {
        "path_to_file": "file1.txt",
        "children": "file2"
    },
    "file2": {
        "path_to_file": "file1.txt",
        "children": "file3,file4"
    },
    "file3": {
        "path_to_file": "a/file3.txt",
        "children": ""
    },
    "file4": {
        "path_to_file": "b/file4.txt",
        "children": ""
    }
}
"""


class Node(object):
    def __init__(self, name, path_to_file=None):
        self.name = name
        self.path_to_file = path_to_file
        self.children = []

    def add_child(self, obj):
        self.children.append(obj)

    def dump(self, indent=0):
        """dump tree to string"""
        tab = '    '*(indent-1) + ' |- ' if indent > 0 else ''
        print('%s%s' % (tab, self.name))
        for obj in self.children:
            obj.dump(indent + 1)


name2info = json.loads(json_string)


def get_tree(name):
    info = name2info[name]
    root = Node(name, info['path_to_file'])
    for child in info['children'].split(","):
        if child:
            root.add_child(get_tree(child))
    return root


root = get_tree('file1')

# get children info
print(root.name, root.children[0].name, root.children[0].children[1].path_to_file)

root.dump()

it outputs:

file1 file2 b/file4.txt
file1
 |- file2
     |- file3
     |- file4
Sign up to request clarification or add additional context in comments.

4 Comments

Thx. So now I can generate the it as: Node(key,value.get("path_to_file") But I'm not sure how I can return the whole tree type ?
awesome! Works perfectly. can you explain a bit about the logic?
1. Create a node based on the name passed in, 2. If the node has children, initialize it (repeat 1-2) and join the chidren attribute of this node. 3. Finally return the entire node, The whole process is recursive thinking
The only problem I have with this solution is that you specify root = get_tree('file1') - I need it to be detected from the Json.. The root isn't always the first one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.