0

I have nested python dictionary like this.

d = {}
d[a] = b
d[c] = {1:2, 2:3}

I am trying to recursively convert the nested dictionary into an xml format since there can be more nested dictionary inside such as d[e] = {1:{2:3}, 3:4}. My desired XML format is like this

<root>
  <a>b</a>
  <c>
    <1>2</1> 
    <2>3</3>
  </c> 
</root>

I have so far this python code to handle nested xml using lxml library. But it doesn't give me the desired output.

def encode(node, Dict):  
  if len(Dict) == 0:  
    return node 
  for kee, val in Dict.items():  
    subNode = etree.SubElement(node, kee) 
    del msgDict[kee]  
    if not isinstance(val, dict): 
      subNode.text = str(val) 
    else: 
      return encode(subNode, val)

Any help is appreciated. Thank you.

pseudo
  • 385
  • 2
  • 19
  • 1
    have you looked as this answer? http://stackoverflow.com/questions/1019895/serialize-python-dictionary-to-xml – Rob Oct 11 '16 at 19:39
  • yea I did. But I was trying to write a native method instead of using external library. It should be fairly straightforward, but my recursive thinking is kinda poor. – pseudo Oct 11 '16 at 19:54
  • You have the right idea. If the current element is another dictionary you want to do a recursion, if it is an element then write it out its value. What is the output you are getting? – Rob Oct 11 '16 at 20:15

2 Answers2

1

The way you recall encode does not look correct. Maybe this helps. For simplicity I just append stuff to a list (called l). Instead, you should do your etree.SubElement(...).

def encode(D, l=[]):
    for k, v in D.items():
        if isinstance(v, dict):
            l2 = [k]
            encode(v, l2)
            l.append(l2)
        else:
            l.append([k, v])
Mehdi
  • 679
  • 4
  • 10
  • I see. It works, too. But I am working with a lot of key,value pairs and converting them to list and dict back and forth will be time-consuming. – pseudo Oct 19 '16 at 21:49
0

I found the bug in my code, which is I didn't return the recursive call back to the original loop. After going inside nested elements, it "returns" and doesn't get back to original loop. Instead of return encode(subNode, val), saving in a variable element = encode(subNode, val) solves the problem.

pseudo
  • 385
  • 2
  • 19