Python ElementTree 重复项检查器
我需要写一个“重复检查器”,用来比较两个XML文件,看看它们是否相同(也就是里面的数据是否一样)。因为这两个XML文件来自同一个类,并且是根据一个XSD生成的,所以它们的结构和元素的顺序很可能是一样的。
我想到的最好的方法是建立两个字典(dictLeft,dictRight),把xpath#value作为键,出现的次数作为值。大概是这样的:
左边:
{ 'my/path/to/name#greg': 1, 'my/path/to/name#john': 2, 'my/path/to/car#toyota': 1}
右边:
{ 'my/path/to/name#greg': 1, 'my/path/to/name#bill': 1, 'my/path/to/car#toyota': 1}
比较这两个字典可以让我比较准确地判断这两个XML文件是否相同(虽然有可能会出现错误的结果,但这种情况非常少)。
有没有人有更好的主意?也许在ElementTree中有我不知道的函数?
补充说明:为了更好地解释:
<root><person><name>Bob</name><surname>marley</surname></root>
和
<root><person><surname>marley</surname><name>Bob</name></root>
会被认为是相同的。我不考虑属性。我的想法是尽量保持代码简单,同时又不影响性能太多。
4 个回答
0
根据你的例子,看起来你可以使用iterparse这个方法,并结合collections.Counter来统计每个标签及其属性出现的次数,把它们当作计数器的键。
例如:
from xml.etree import cElementTree as ElementTree
from collections import Counter
your_xml = get_xml()
count = Counter()
parser = ElementTree.iterparse(your_xml)
for event, element in parser:
#joining string as key for ease of debugging, strictly speaking,
#one could use a tuple and save the str() on the attrib dict
key = "".join((element.tag, str(element.attrib), element.text))
count[element.tag] += 1
另外,你也可以把计数用一个普通的字典来实现,然后直接比较这两个字典是否相等(在我看来,这样的概念更简单)。
0
如果两个XML文件是从同一段代码生成的,并且里面的值(顺序也要一样)都是相同的,那么你可以直接把这两个XML的数据当作字符串来比较。
如果这样比较能成功,那可能就是最简单的解决办法了。不过,也有可能会有一些原因导致这种方法不适合你。
1
好的,我需要做个决定,最后选择了这个:
foreach path in xpathlist
find entries for path for both xml1 and xml2
foreach entry in xmlentries1
dict1[path#entry.value]++
foreach entry in xmlentries2
dict2[path#entry.value]++
if dict1 and dict2 are not equal
return false
return true
我希望这样说能让你明白。这让我可以测试特定的或者所有的xpath。如果有人有更好的算法,我非常乐意听听 :)