2014-08-06 5 views
3

У меня есть этот нелогич- текстового файла: (я не знаю, что вы называете это, а дерево?)Создание объекта JSON из текстового файла с закладками дерева

key1 
    subkey1 
    subkey2 
     choice1 
key2 
    subkey1 
    subkey2 

Я хочу, чтобы выглядеть следующим образом:

[ 
    { 
     "text":"key1", 
     "children":[ 
      { 
       "text":"subkey1", 
       children:[] 
      }, 
      { 
       "text":"subkey2", 
       children:[ 
        { 
         "text":"choice1", 
         "children":[] 
        } 
       ] 
      }, 
     ] 
    }, 
    { 
     "text":"key2", 
     "children":[ 
      { 
       "text":"subkey1", 
       children:[] 
      }, 
      { 
       "text":"subkey2", 
       children:[] 
      }, 
     ] 
    } 
] 

Это то, что Я делаю, я не понимаю, как вы получите дочерние элементы в родительском, и это должно быть в состоянии идти бесконечно глубоко.

import itertools 
def r(f, depth, parent, l, children): 
    for line in f: 
     line = line.rstrip() 
     newDepth = sum(1 for i in itertools.takewhile(lambda c: c=='\t', line)) 
     node = line.strip() 
     if parent is not None: 
      print parent, children 
      children = [{"txt":node, "children":[]}] 
      # l.append({"txt":parent, "children":children}) 
     r(f, newDepth, node, l, children) 
json_list = [] 
r(open("test.txt"), 0, None, json_list, []) 
print json_list 

ответ

5

Первого правило, избежать рекурсий, если вы можете ... Здесь вам нужно только знать предок, и они могут быть легко поддерживать в списке. Обратите внимание, что depth 0 зарезервировано для корневого узла, а первая «пользовательская» глубина - 1, поэтому +1 при подсчете вкладок.

f = open("/tmp/test.txt", "r") 

depth = 0 
root = { "txt": "root", "children": [] } 
parents = [] 
node = root 
for line in f: 
    line = line.rstrip() 
    newDepth = len(line) - len(line.lstrip("\t")) + 1 
    print newDepth, line 
    # if the new depth is shallower than previous, we need to remove items from the list 
    if newDepth < depth: 
     parents = parents[:newDepth] 
    # if the new depth is deeper, we need to add our previous node 
    elif newDepth == depth + 1: 
     parents.append(node) 
    # levels skipped, not possible 
    elif newDepth > depth + 1: 
     raise Exception("Invalid file") 
    depth = newDepth 

    # create the new node 
    node = {"txt": line.strip(), "children":[]} 
    # add the new node into its parent's children 
    parents[-1]["children"].append(node) 

json_list = root["children"] 
print json_list 
+0

Большое спасибо, thats perfect! – Harry

Смежные вопросы