我对两个xml元素的等价性很感兴趣;我发现测试元素的tostring是可行的;然而,这似乎有点老生常谈。
有没有更好的方法来测试两个etree元素的等价性?
直接比较元素:
import xml.etree.ElementTree as etree
h1 = etree.Element('hat',{'color':'red'})
h2 = etree.Element('hat',{'color':'red'})
h1 == h2 # False
将元素作为字符串进行比较:
etree.tostring(h1) == etree.tostring(h2) # True
发布于 2014-06-22 17:29:35
此比较函数适用于我:
def elements_equal(e1, e2):
if e1.tag != e2.tag: return False
if e1.text != e2.text: return False
if e1.tail != e2.tail: return False
if e1.attrib != e2.attrib: return False
if len(e1) != len(e2): return False
return all(elements_equal(c1, c2) for c1, c2 in zip(e1, e2))
发布于 2013-08-28 20:55:05
序列化和反序列化不适用于XML,因为属性不依赖于顺序(和其他原因),例如,这两个元素在逻辑上相同,但字符串不同:
<THING a="foo" b="bar"></THING>
<THING b="bar" a="foo" />
确切地说,如何进行元素比较是很棘手的。据我所知,Element Tree中没有任何内置的东西可以为您做这件事。我需要自己做这件事,并使用了下面的代码。它可以满足我的需求,但它不适合大型XML结构,而且速度和效率都不高!这是一个排序函数,而不是相等函数,因此0的结果是相等的,其他任何值都不相等。使用True或False返回函数包装它,留给读者作为练习!
def cmp_el(a,b):
if a.tag < b.tag:
return -1
elif a.tag > b.tag:
return 1
elif a.tail < b.tail:
return -1
elif a.tail > b.tail:
return 1
#compare attributes
aitems = a.attrib.items()
aitems.sort()
bitems = b.attrib.items()
bitems.sort()
if aitems < bitems:
return -1
elif aitems > bitems:
return 1
#compare child nodes
achildren = list(a)
achildren.sort(cmp=cmp_el)
bchildren = list(b)
bchildren.sort(cmp=cmp_el)
for achild, bchild in zip(achildren, bchildren):
cmpval = cmp_el(achild, bchild)
if cmpval < 0:
return -1
elif cmpval > 0:
return 1
#must be equal
return 0
发布于 2011-10-27 00:59:28
信不信由你,如果你不知道两个节点可能有多少个子节点,并且你想在搜索中包含所有的子节点,那么这实际上是处理比较两个节点的最好方法。
当然,如果您只有一个没有子节点的节点,那么您可以简单地比较tag、attrib和tail属性:
if h1.tag == h2.tag and h1.attrib == h2.attrib and h1.tail == h2.tail:
print("h1 and h2 are the same")
else
print("h1 and h2 are the different")
然而,与使用tostring相比,我看不出这有什么大的好处。
https://stackoverflow.com/questions/7905380
复制相似问题