一切都取决于您对“等效”的定义。
假设您只关心文本节点(例如:您的示例中的d
标签甚至不重要,您只关心内容word
),则可以创建每个文档的文本节点集并进行比较。使用lxml,代码如下:
from lxml import etree
tree1 = etree.parse('example1.xml')
tree2 = etree.parse('example2.xml')
print set(tree1.getroot().itertext()) == set(tree2.getroot().itertext())
你甚至可能想忽略空格节点,可以采取以下方式:
```python
你的代码示例
```
```javascript
你的代码示例
```
set(i for i in tree.getroot().itertext() if i.strip())
请注意,使用集合意味着您将不考虑文档中某些文本出现的次数(这可能是您想要的,也可能不是)。如果顺序不重要,但出现次数重要,则可以使用字典代替集合,并跟踪出现次数(例如,在Python 2.7中使用
collections.defaultdict()
或
collections.Counter
)。
但是,如果只有根元素的直接子元素的顺序(在您的情况下,
a
元素的子元素)可以被忽略,并且这些元素内部的所有内容都很重要,则需要另一种方法。例如,您可以对每个子元素进行XML规范化,以获取每个子元素的规范化版本(同样,我不知道这是否足够规范化满足您的需求)。
from lxml import etree
tree1 = etree.parse('example1.xml')
tree2 = etree.parse('example2.xml')
set1 = set(etree.tostring(i, method='c14n') for i in tree1.getroot())
set2 = set(etree.tostring(i, method='c14n') for i in tree2.getroot())
print set1 == set2
注意:为了使示例更简单,我使用了lxml的开发版本,在旧版本中,
etree.tostring()
没有
method='c14n'
,只有一个在ElementTree上写入类似文件对象的
c14n()
方法。因此,在那里让它工作,您必须将每个元素复制到自己的树中,并使用
StringIO()
对象作为虚拟文件。同时,这种做法可能不适用于非常大的文件。
但是请注意:强烈警告 - 您必须确切知道您所需要的“等效”,并基于该知识创建自己的解决方案!