2014-11-04 84 views
0

我有數百個xml文件。我有函數來比較2 xml樹,並返回true,如果它們是相同的。每個xml樹都有唯一的id號,在比較中被忽略。將樹保存爲字典中的鍵,Python 3.4

現在我可以迭代所有的xml文件並進行比較。但我想將這些樹保存在像字典這樣的數據結構中。但python不允許我將樹保存爲一個關鍵字,並將其id作爲一個值。 有沒有辦法讓樹的字典作爲關鍵?如果不是,那麼可以使用什麼類型的數據結構呢?

例如: enter image description here

注意樹1 = Tree2但是= Tree3(忽略ID),所以我想我的DIC或任何數據結構是這樣的:!

dic = {Tree1:[I1.i1.p1.m1, I1.i1.p1.m2], Tree3: [I1.i1.p1.m3]} 

感謝

+0

你能提供一個**文本**例子和一些實際的代碼嗎?通常,對象必須實現'__hash__'和'__eq__'作爲字典鍵。 – jonrsharpe 2014-11-04 12:27:39

+0

並非所有內容都可以是字典鍵,請閱讀http://www.tutorialspoint.com/python/python_dictionary.htm搜索頁面中的「限制」。 – 2014-11-04 14:08:58

回答

0

字典是HashMap。這意味着鍵必須是可哈希的,這通常意味着要被哈希的對象是不可變的(爲什麼列表不是有效鍵,而是元組)。

你需要的是一個爲你的對象生成哈希的函數。在樹形數據結構上生成散列是一個不小的問題。但是,既然您已經可以制定平等,則您必須瞭解一些可以使您的數據可識別的功能。

您始終可以在特徵向量上構建散列。可以使用的功能:

  1. 樹的深度
  2. 兒童
  3. 散在已經可用的序列化
0

這裏的通用解決方案,讓說,如果2個XML樹是數除特定屬性外,其他內容完全相同

import xml.etree.ElementTree as ET 

xml1 = '<?xml version="1.0" encoding="utf-8" ?><Math mode="inline" tau="tex" xml:id="foo"><XMath>2x+3c</XMath></Math>' 
xml2 = '<Math mode="inline" tau="tex" xml:id="bar"><XMath>2x+3c</XMath></Math>' 

#see for more informations https://docs.python.org/3.4/library/xml.etree.elementtree.html 

def almost_equals(tree1, tree2, attributes_to_ignore): 
    """ Return true or false depending on the fact that tree1 and tree2 are identical except for the attributes whose the tag is in attributes to ignore. """ 
    #remove attributes to ignore 
    for attribute in attributes_to_ignore: 
     try: 
      tree1.attrib.__delitem__(attribute) 
     except: 
      pass  
     try: 
      tree2.attrib.__delitem__(attribute) 
     except: 
      pass 

    #compare nodes 
    if tree1.tag != tree2.tag: 
     print(tree1.tag,"!=",tree2.tag) 
     return False 

    if tree1.attrib != tree2.attrib: 
     print(tree1.attrib,"!=",tree2.attrib) 
     return False 

    if tree1.text != tree2.text: 
     print(tree1.text,"!=",tree2.text) 
     return False 

    subtrees1 = list(tree1) 
    subtrees2 = list(tree2) 

    if len(subtrees1) != len(subtrees2): 
     return False 

    result = True 
    for i in range(len(subtrees1)): 
     result = result and almost_equals(subtrees1[i], subtrees2[i], attributes_to_ignore) 

    return result 

if __name__ == "__main__": 
    xmlTree1 = ET.fromstring(xml1) 
    xmlTree2 = ET.fromstring(xml2) 
    print("The 2 xml trees are identical ({0})".format(almost_equals(xmlTree1, xmlTree2, ["{http://www.w3.org/XML/1998/namespace}id"]))) 

希望它有幫助。 亞瑟。

編輯:您可以將XML保存爲xml並根據需要解析它們,或者節省由內置python庫生成的Element對象。