Python—将递归抽象为所有N级递归(lxml)

Python—将递归抽象为所有N级递归(lxml),python,xml,Python,Xml,我尝试比较一些几乎相同的XML,并发现:这表明:我有一种测试两个节点的方法 下一步是从基于节点的测试中获取输出,如果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.r

我尝试比较一些几乎相同的XML,并发现:这表明:我有一种测试两个节点的方法

下一步是从基于节点的测试中获取输出,如果
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对象。我怀疑我把函数移动到一个类中弄错了,并且没有给出/得到正确的东西


我想做的是找到错误比较的来源,打印两个有问题的数据元素,并知道它们在这两段XML中的位置(或缺失)

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

编辑:


对于代码的混乱,我深表歉意,但我认为这会满足您的要求。但是,如果不知道如何导入xml模块/内容或正在使用什么xml对象,我就无法测试它。希望这会有所帮助。

我不确定这是否会有帮助,但在Python 3.3中,您可以使用
yield from
,例如,实现决策树(听起来像您正在做的事情),如“实现迭代器协议”中所述:@erewok谢谢,不幸的是,我使用的是2.7。这似乎效率很低-看起来您正在测试完整的树,如果它们不匹配,那么您将迭代检查较小的子集(即重复大量比较,即使比较在第一次不匹配时停止)。最好从最深层次开始进行比较,然后逐步深入到完整的树…@twalberg如果XML文档的结构变化很大,那么实现起来并不容易。如果您要查找树的分叉点,那么您需要能够匹配树,不能在第一次失败时就放弃。@twalberg同样对于具有高度分支的XML,与您在顶层所做的比较相比,您实际上没有重复那么多比较。如果每个节点都有4个子节点,那么您将检查树的内容。感谢您的努力。我一进办公室就玩这个。我不是100%清楚您的示例中发生了什么,但是当我把它放到我的源XML中时,我相信它会更有意义!
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()