2014-12-31 82 views
0

我想弄清楚我正在处理的代码的逻辑。我有一本字典词典。基本上,我正在从文件列表中创建一个Web表单。递归:将嵌套字典转换为XML(HTML)

我很清楚,我需要使用递归函数,但递归位引发了我的思想在百万个方向,我无法弄清楚使这项工作所需的逻辑。

我的字典词典...

{'Desktop': {'bar': {'buz': '/home/michael/t/Desktop/bar/buz', 
        'fuz': '/home/michael/t/Desktop/bar/fuz'}, 
      'foo': {'buz': '/home/michael/t/Desktop/foo/buz', 
        'fuz': '/home/michael/t/Desktop/foo/fuz'}}, 
'Documents': {'bar': {'buz': '/home/michael/t/Documents/bar/buz', 
         'fuz': '/home/michael/t/Documents/bar/fuz'}, 
       'foo': {'buz': '/home/michael/t/Documents/foo/buz', 
         'fuz': '/home/michael/t/Documents/foo/fuz'}, 
       'good title': '/home/michael/t/Documents/good title'}, 
'test.py': '/home/michael/t/test.py'} 

我需要解释变成这样...

<ul id="master"> 
    <li><input type="checkbox" id="Desktop"><label for="Desktop">Desktop</label> 
    <ul> 
     <li><input type="checkbox" id="Desktop/bar"><label for="Desktop/bar">bar</label> 
     <ul> 
      <li><input type="checkbox" id="/home/michael/t/Desktop/bar/buz"><label for="/home/michael/t/Desktop/bar/buz">buz</label></li> 
      <li><input type="checkbox" id="/home/michael/t/Desktop/bar/fuz"><label for="/home/michael/t/Desktop/bar/fuz">fuz</label></li> 
     <ul> 
     </li> 
     <li><input type="checkbox" id="Desktop/bar"><label for="Desktop/foo">bar</label> 
     <ul> 
      <li><input type="checkbox" id="/home/michael/t/Desktop/foo/buz"><label for="/home/michael/t/Desktop/foo/buz">buz</label></li> 
      <li><input type="checkbox" id="/home/michael/t/Desktop/foo/fuz"><label for="/home/michael/t/Desktop/foo/fuz">fuz</label></li> 
     <ul> 
     </li> 
    </ul> 
    </li> 
    <li><input type="checkbox" id="Documents"><label for="Documents">Desktop</label> 
    <ul> 
     <li><input type="checkbox" id="Documents/bar"><label for="Documents/bar">bar</label> 
     <ul> 
      <li><input type="checkbox" id="/home/michael/t/Documents/bar/buz"><label for="/home/michael/t/Documents/bar/buz">buz</label></li> 
      <li><input type="checkbox" id="/home/michael/t/Documents/bar/fuz"><label for="/home/michael/t/Documents/bar/fuz">fuz</label></li> 
     <ul> 
     </li> 
     <li><input type="checkbox" id="Documents/bar"><label for="Documents/foo">bar</label> 
     <ul> 
      <li><input type="checkbox" id="/home/michael/t/Documents/foo/buz"><label for="/home/michael/t/Documents/foo/buz">buz</label></li> 
      <li><input type="checkbox" id="/home/michael/t/Documents/foo/fuz"><label for="/home/michael/t/Documents/foo/fuz">fuz</label></li> 
     <ul> 
     </li> 
     <li><input type="checkbox" id="/home/michael/t/Documents/good title"><label for="/home/michael/t/Documents/good title">good title</label></li> 
    </ul> 
    </li> 
    <li><input type="checkbox" id="/home/michael/t/test.py"><label for="/home/michael/t/test.py">test.py</label></li> 
</ul> 

递归绝对是一个谜,我和这个人是(我)一个相当先进的难题。

我最伤心的尝试到目前为止...

def print_form(dictionary, root): 
    ''' 
    Remove the root of the dictionary and then build the form. 
    ''' 
    r = root.split('/') 
    listing = dictionary[r[0]][r[1]][r[2]][r[3]] 
    return '<ul id="master">{}</ul>'.format(build_xml('', listing)) 


def build_xml(group, listing): 
    for k, v in listing.iteritems(): 
     if type(v) == dict: 
      return '<ul><li><input type="checkbox" id="{0}"><label for="{0}">{1}</label></li>{2}</ul>'.format(group + '/' + k, k, build_xml(group + '/' + k, v)) 
     elif type(v) == str: 
      return '<li><input type="checkbox" id="{0}"><label for="{0}">{1}</label></li>'.format(v, k) 
+0

...到目前为止你到底尝试了什么? –

+0

@PeterVaro我认为问题是他不知道从哪里开始。 – augurar

+0

我尝试了很多东西,但他们准确地反映了我缺乏知识和技能。我离开了我的尝试,因为他们很尴尬和可悲。 – MTeck

回答

1

我认为(希望)这样做的工作:

from xml.etree import ElementTree 
import os 

def dict_to_xml(dict_, parent_node=None, parent_name=''): 
    def node_for_value(name, value, parent_node, parent_name): 
     """ 
     creates the <li><input><label>...</label></input></li> elements. 
     returns the <li> element. 
     """ 
     value= os.path.join(parent_name, value) 
     node= ElementTree.SubElement(parent_node, 'li') 
     child= ElementTree.SubElement(node, 'input') 
     child.set('type', 'checkbox') 
     child.set('id', value) 
     child= ElementTree.SubElement(child, 'label') 
     child.set('for', value) 
     child.text= name 
     return node 

    # create an <ul> element to hold all child elements 
    if parent_node is None: 
     node= ElementTree.Element('ul') 
     node.set('id', 'master') 
    else: 
     node= ElementTree.SubElement(parent_node, 'ul') 

    # add the sub-elements 
    for key,value in dict_.iteritems(): 
     if isinstance(value, dict): 
      child= node_for_value(key, key, node, parent_name) 
      dict_to_xml(value, child, key) 
     else: 
      node_for_value(key, value, node, parent_name) 
    return node 

这将返回ElementTree.Element,你可以将其转换为xml像这样:

dict_to_xml(my_dict).tostring() 

,或者得到格式的XML(用于调试):

element= dict_to_xml(my_dict) 

from xml.dom import minidom 

xml= ElementTree.tostring(element) 
xml= minidom.parseString(xml) 
xml= xml.toprettyxml(indent=' ') 
+0

这工作绝对完美!这看起来比我能想到的任何事情都要多得多,但也要更加健壮和灵活。我想明白这一点......会带我一大堆盯着。 – MTeck