Python - show an XML file on a TreeView structure

3.9k Views Asked by At

I have this code that tranverse a dict object and put it on a TreeView. For simple xml it gets ok but with complex xml it doesn't work.

The problem is with the walk_dict function, but I can't get it right.

#-*- encoding: utf8 -*-
from Tkinter import *
from ttk import Treeview
import xmltodict

class App:

  def __init__(self, root):

    try:
      self.tagsoup = xmltodict.parse(file(sys.argv[1],'r').read())
      self.tree = Treeview(root, height=30)
      self.tree.pack()
      self.last = ''
      self.walk_dict(self.tagsoup)
    except Exception as e:
      print e

  def walk_dict(self, d,depth=0):
    for k,v in sorted(d.items(),key=lambda x: x[0]):
      if isinstance(v, dict):
        self.last = k
        self.tree.insert('', 'end', k, text = k)
        self.walk_dict(v,depth+1)
      else:
        self.tree.insert(self.last, 'end', k, text = k)
        self.tree.insert(k, 'end', v, text = v)

root = Tk()
App(root)
root.mainloop()

The xml I am feeding is this:

<menu>
    <opcao1>Aspargos</opcao1>
    <opcao2>Tomate frito</opcao2>
    <opcao3>Abóbora caramelizada</opcao3>
    <opcao4>Churrasco de ovelha</opcao4>
    <opcao5>Pizza</opcao5>
    <opcao6>
        <lol>Copter</lol>
        <meh>lolcopter</meh>
        <bla>
            <woo>foo</woo>
        </bla>
    </opcao6>
</menu>

This is the output This is the output. Note that opcao6 is rendered out of the tree, and its children are rendered below.

1

There are 1 best solutions below

0
On BEST ANSWER

The problem is that no matter how deep your recursion, you're always creating items as children of the root item. Instead, you need to save the id of the new item, and pass that in as a new parent when you make a nested call to walk_dict.

It would look something like this:

def walk_dict(self, d,depth=0, parent=""):
  for k,v in sorted(d.items(),key=lambda x: x[0]):
    item = self.tree.insert(parent, 'end', k, text = k)
    if isinstance(v, dict):
      self.walk_dict(v,depth+1, parent=item)
    else:
      self.tree.insert(item, 'end', v, text = v)