所以我必须编写一个“重复检查器”来比较两个XML并查看它们是否相同(包含相同的数据)。现在因为它们来自同一个类并且是从XSD生成的结构,内部元素的顺序很可能是相同的。
我能想到进行重复检查的最好方法是设置两个字典(dictLeft,dictRight)并将xpath#值保存为密钥及其出现的次数。像这样:
左:
{ '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>
将被视为相同。我无视属性。我们的想法是尽可能简化代码,同时不要过多地影响性能。
答案 0 :(得分: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。如果有人有更好的算法,我会全力以赴:)
答案 1 :(得分: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
或者,将数量计算为正常的dict并且只比较两个dicts的相等性(在概念上对我来说似乎更简单)。
答案 2 :(得分:0)
如果从同一代码生成两个XML并包含相同的值(按相同顺序),那么您可以简单地对XML数据进行字符串比较。
如果可行,则可能是简单的解决方案,但可能有理由说明为什么这对您不起作用。
答案 3 :(得分:0)
这个问题始于定义“相同”的含义。
例如,对于XML元素,一个简单的相等定义是,如果符合以下两个XML元素:
为什么这个微不足道的定义可能不够,有各种各样的原因:
normalize-space()
函数)一旦定义了相等性,实现测试它的方法就相对简单了。但是你需要先定义平等。