Python - 抽象递归到所有第n级递归(lxml)

时间:2013-08-29 21:02:44

标签: python xml

我有一些几乎相同的XML,我试图比较,并找到了这个:Compare XML snippets?指出这个:https://bitbucket.org/ianb/formencode/src/tip/formencode/doctest_xml_compare.py#cl-70我有一种测试两个节点的方法。

下一步是从基于节点的测试中获取输出,如果False,则进入所有子节点,然后重复测试。

我已经写了很长的路,这让我可以通过尽可能多的孩子来编写代码:

 if xml.xml_compare(a.root, b.root) == False:
    for i, node in enumerate(a.root):
        if xml.xml_compare(a.root[i], b.root[i]) == False:
            for j, node in enumerate(a.root[i]):
                if xml.xml_compare(a.root[i][j], b.root[i][j]) == False:
                    for k, node in enumerate(a.root[i][j]):
                        ....
                            if xml.xml_compare(a.root[i][j][k][l][m][n], b.root[i][j][k][l][m][n]) == False:

这显然不适合任意大小的XML,而且它不是很优雅。我想我需要编写一个生成器来处理测试中的XML - 我看到itertool是这样做的一种方式:

class XML_Tools(object):
    ....
    def iterparent(self, xml_object):
    """ 
    returns the parent and children of a node
    """
    for parent in xml_object.getiterator():
        for child in parent:
            yield self.parent, self.child

    main():
    a = ET.parse(open(file_a, "r")
    b = ET.parse(open(file_b, "r")
    xml.iterparent(a.root)
    for xml.parent, xml.child in xml.iterparent(a.root):
        print xml.parent, xml.child

但我无法找到一种方法来获取可以运行的xml.parent或xml.child对象。我怀疑我把这个功能搞砸到一个班级,而不是给予/得到正确的东西。

我想要做的是找到False比较的来源,并打印两个有问题的数据元素,并知道它们在两个XML中的存在(或缺失)。

1 个答案:

答案 0 :(得分:3)

我建议使用递归算法,该算法将要比较的2个项目列表和传递号码作为参数。您需要一个字典来指定每次传递时要提供的列表。您还可以编写一个算法来创建n个元素的字典,希望这会有所帮助。我可以尝试提供示例代码,如果它更有用。

编辑:

n=3 ##Depth of tree

d={'0':['a.root', 'b.root', 0]}

for i in range(n):
    d[str(i+1)]=[d[str(i)][0]+'['+chr(105+i)+']', #since ord('i')=105, start
                 d[str(i)][1]+'['+chr(105+i)+']', # at i, j, k, etc
                 i+1                              #passNo
                ]

print(d)

def compare(points=d['0'], passNo=0):
    if xml.xml_compare(eval(points[0]), eval(points[1])) == False:
        exec('for'+str(chr(points[2]+105))+'in enumerate('+str(points[0])+\
             '): compare('+str(d[str(passNo+1)][0])+', '+str(d[str(passNo+1)][1])+')')

compare()

我为代码的混乱而道歉,但我认为这会做你想要的。但是,如果不知道如何导入xml模块/内容或者正在使用的xml对象,我无法测试它。希望这会有所帮助。