2013-08-29 52 views
4

我有一些幾乎相同的XML,我試圖比較,並且發現了這個:Compare XML snippets?這指出了這一點:https://bitbucket.org/ianb/formencode/src/tip/formencode/doctest_xml_compare.py#cl-70我有一種測試兩個節點的方法。Python - 抽象遞歸到所有的第n級遞歸(lxml)

下一步是從基於節點的測試中取出輸出,並且如果步入所有的孩子並重複測試。

我已經寫了沃克的很長的路,可以讓我通過儘可能多的孩子一步,因爲我想要寫代碼:

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,其不是很優雅。我thnk我需要寫一個發電機行走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中丟失)。

+0

遞歸是方式 – BlackBear

+2

我不確定這是否會有所幫助,但在Python 3.3中,例如,可以使用'yield from'來實現類似決策樹的東西(這聽起來像你的東西做)在配方「實施迭代協議」:http://chimera.labs.oreilly.com/books/1230000000393/ch04.html#_discussion_59 – erewok

+0

@erewok謝謝,我在2.7不幸。 –

回答

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對象的。希望這可以幫助。

+0

謝謝你的努力。當我進入辦公室時,我會玩這個遊戲。我不是100%清楚你的例子中發生了什麼,但是當我把它放在我的源XML中時,我相信它會變得更有意義! –