如何检查两个XML文档的等效性?

时间:2018-09-27 12:56:04

标签: python xml python-3.x xslt

在我的程序中,我调用了命令行XSLT处理器(例如Saxon或xsltproc)。

然后(出于测试目的)我想将处理器的输出与预定义的字符串进行比较。

问题在于XML的格式可以不同。以下三个是不同的字符串:

<?xml version="1.0" encoding="utf-8"?>
<x/>

<?xml version="1.0"?>
<x/>

<?xml version="1.0"?>
<x
/>

如何检查来自不同XSLT处理器的输出以匹配给定的XML字符串?

也许有一种方法(不一定标准化)可以使不同的XSLT处理器输出完全相同的结果?

我使用Python 3。

3 个答案:

答案 0 :(得分:2)

您是否看过使用像XSpec这样的测试框架已经解决了这个问题?

通常,解决此问题的两种经典方法是在对序列化的XML进行规范化之后按词法比较序列化的XML,或者使用诸如XPath 2.0 deep-equal()之类的函数来比较树的表示形式。

这些都不是完美的答案。首先,XML规范化认为重要或不重要的事物可能与您认为重要或不重要的事物不同; XPath deep-equal()也是如此。其次,您不仅要知道文件是否相同,还要知道差异在哪里。

Saxon具有deep-equal()的增强版本saxon:deep-equal(),旨在解决这些问题:它带有一组可用于自定义比较的标志,并试图告诉您差异在哪里就警告消息而言。但这也不是完美的解决方案。

在针对XSLT 3.0和XQuery的W3C测试套件中,我们已经不再将测试的XML输出进行比较,而是根据预期的XPath表达式编写断言。测试使用如下断言:

  <result>
     <all-of>
        <assert>every $a in /out/* except /out/a4 
                satisfies $a/@actual = $a/@expected</assert>
        <assert>/out/a4/@actual = 'false'</assert>
     </all-of>
  </result> 

答案 1 :(得分:0)

您在乎订单吗?如果不是:

将它们转换为字典,然后对它们运行deepdiff!

答案 2 :(得分:0)

使用minidom可以轻松完成:

from unittest import TestCase

from defusedxml.minidom import parseString


class XmlTest(TestCase):
    def assertXmlEqual(self, got, want):
        return self.assertEqual(parseString(got).toxml(), parseString(want).toxml())