简体   繁体   English

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

[英]How to check equivalence of two XML documents?

From my program I call a command line XSLT processor (such Saxon or xsltproc). 从我的程序中,我调用了命令行XSLT处理器(例如Saxon或xsltproc)。

Then (for testing purposes) I want to compare the output of the processor with a predefined string. 然后(出于测试目的)我想将处理器的输出与预定义的字符串进行比较。

The trouble is that XML can be formatted differently. 问题在于XML的格式可能不同。 The following three are different strings: 以下三个是不同的字符串:

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

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

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

How to check output from different XSLT processors to match a given XML string? 如何检查来自不同XSLT处理器的输出以匹配给定的XML字符串?

Maybe there is a way (not necessarily standartized) for different XSLT processors to output exactly the same? 也许有一种方法(不一定标准化)可以使不同的XSLT处理器输出完全相同的输出吗?

I use Python 3. 我使用Python 3。

Have you looked at using a testing framework like XSpec that already addresses this issue? 您是否在考虑使用像XSpec这样的测试框架已经解决了这个问题?

Typically the two classic ways of solving this are to compare the serialized XML lexically after putting it through a canonicalizer, or to compare the tree representations using a function such as XPath 2.0 deep-equal(). 通常,解决此问题的两种经典方法是将序列化的XML通过规范化后按词法比较,或使用诸如XPath 2.0 deep-equal()之类的函数比较树表示形式。

Neither of these is a perfect answer. 这些都不是完美的答案。 Firstly, the things which XML canonicalization considers to be significant or insignificant may not be the same as the things you consider significant or insignificant; 首先,XML规范化认为重要或不重要的事物可能与您认为重要或不重要的事物不同; and the same goes for XPath deep-equal() . XPath deep-equal() Secondly, you really want to know not just whether the files are the same, but where the differences are. 其次,您不仅要知道文件是否相同,还要知道差异在哪里。

Saxon has an enhanced version of deep-equal() called saxon:deep-equal() designed to address these issues: it takes a set of flags that can be used to customize the comparison, and it tries to tell you where the differences are in terms of warning messages. Saxon有一个称为saxon:deep-equal()的增强版本的deep-equal()旨在解决这些问题:它带有一组可用于自定义比较的标志,并且它试图告诉您差异在哪里在警告消息方面。 But it's not a perfect solution either. 但这也不是完美的解决方案。

In the W3C test suites for XSLT 3.0 and XQuery we've moved away from comparing XML outputs of tests to writing assertions against the expected results in terms of XPath expressions. 在针对XSLT 3.0和XQuery的W3C测试套件中,我们已经从比较测试的XML输出转向根据预期的XPath表达式编写断言。 The tests use assertions like this: 测试使用如下断言:

  <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> 

Do you care about the order? 您关心订单吗? IF NOT: 如果不:

Convert them to a dictionary then run deepdiff on them! 将它们转换为字典,然后对它们运行deepdiff!

It can be easily done with minidom : 可以很轻松地做到以下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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM