比较 XmlDocument 的相等性(内容方面)
如果我想比较一个XMlDocument的内容,是不是就这样?
XmlDocument doc1 = GetDoc1();
XmlDocument doc2 = GetDoc2();
if(doc1 == doc2)
{
}
我不检查它们是否都是相同的对象引用,而是检查 xml 的内容是否相同。
If I want to compare the contents of a XMlDocument, is it just like this?
XmlDocument doc1 = GetDoc1();
XmlDocument doc2 = GetDoc2();
if(doc1 == doc2)
{
}
I am not checking if they are both the same object reference, but if the CONTENTS of the xml are the same.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
尝试DeepEquals 方法。
另请参阅 LINQ to XML 树
Try the DeepEquals method on the XLinq API.
See also Equality Semantics of LINQ to XML Trees
不。 XmlDocument 不会覆盖
Equals()
方法 的行为,因此,它实际上只是执行引用相等 - 这在您的示例中将会失败,除非文档实际上是同一个对象实例。如果您想比较文档的内容(属性、元素、注释、PI 等),您必须自己实现该逻辑。 请注意:这并不简单。
根据您的具体情况,您也许能够从文档中删除所有非必要的空格(这本身可能很棘手),然后它们会比较生成的 xml 文本。这并不完美 - 对于语义相同但在命名空间的使用和声明方式、某些值是否转义、元素顺序等方面有所不同的文档,它会失败。正如我之前所说,XML 比较并非微不足道。
您还需要清楚地定义两个 XML 文档“相同”的含义。元素或属性顺序重要吗?大小写(在文本节点中)重要吗?您应该忽略多余的 CDATA 部分吗?处理指令算不算?完全限定命名空间与部分限定命名空间怎么样?
在任何通用实现中,您可能希望将两个文档转换为某种规范形式(XML 或其他表示形式),然后比较规范化内容。
已经存在执行 XML 差异的工具,例如 Microsoft XML Diff/Patch,您可以利用它来识别两个文档之间的差异。据我所知,该工具不是以源代码形式分发的......因此,要在嵌入式应用程序中使用它,您需要编写该过程的脚本(如果您打算使用它,您应该首先验证许可条款是否允许它的使用和重新分发)。
编辑: 查看@Max Toro 的回答(如果您使用的是 .NET 3.5 SP1),显然 XLinq 中的一个选项可能会有所帮助。很高兴知道它的存在。
No. XmlDocument does not override the behavior of the
Equals()
method so, it is in fact just performing reference equality - which will fail in your example, unless the documents are actually the same object instance.If you want to compare the contents (attributes, elements, commments, PIs, etc) of a document you will have to implement that logic yourself. Be warned: it's not trivial.
Depending on your exact scenario, you may be able to remove all non-essential whitespace from the document (which itself can be tricky) and them compare the resulting xml text. This is not perfect - it fails for documents that are semantically identical, but differ in things like how namespaces are used and declared, or whether certain values are escaped or not, the order of elements, and so on. As I said before, XML comparison is not trivial.
You also need to clearly define what it means for two XML documents to be "identical". Does element or attribute ordering matter? Does case (in text nodes) matter? Should you ignore superfluous CDATA sections? Do processing instructions count? What about fully qualified vs. partially qualified namespaces?
In any general purpose implementation, you're likely going to want to transform both documents into some canonical form (be it XML or some other representation) and then compare the canonicalized content.
Tools already exist that perform XML differencing, like Microsoft XML Diff/Patch, you may be able to leverage that to identify differences between two documents. To my knowledge that tool is not distributed in source form ... so to use it in an embedded application you would need to script the process (if you plan to use it, you should first verify that the licensing terms allow it's use and redistribution).
EDIT: Check out @Max Toro's answer if you're using .NET 3.5 SP1, as apparently there's an option in XLinq that may be helpful. Nice to know it exists.
一种简单的方法是比较
OuterXml
。A simple way could be to compare
OuterXml
.我知道这个问题有多老了,但我必须通过多个来源才能找到我正在寻找的答案。以下使用 XNode.DeepEquals 但也忽略属性顺序。在这个问题首次提出 13 年后,我需要做大量的工作才能得出这个答案,我想其他人可能会发现这个答案很有帮助。
使用 NUnit 作为我的测试套件,您可以传入 2 个 XmlDocuments 或一个 XmlDocument 和字符串。这会将 XmlDocuments 转换为 XDocuments,对每个节点的属性进行排序,然后执行 XNode.DeepEquals()。
代码
I know how old this question is but I had to go through multiple sources to find the answer I was looking for. The following is using the XNode.DeepEquals but also ignores the attribute order. With the amount of work I had to do to come up with this answer 13 years after this question was first asked I figure someone else may find this answer helpful.
Using NUnit as my testing suite, you can pass in either either 2 XmlDocuments or an XmlDocument and string. This converts the XmlDocuments into XDocuments, sorts the attributes for every node then does the XNode.DeepEquals().
Code
LBushkin 是对的,这不是小事。由于 XML 是字符串数据,从技术上讲,您可以对内容执行哈希并进行比较,但这会受到空格等因素的影响。
您可以在两个文档之间执行结构化差异(也称为“XML diffgram”)并比较结果。例如,这就是 .NET 数据集跟踪更改的方式。
除此之外,您必须遍历 DOM 并将元素、属性和值相互比较。如果涉及到模式,那么您还必须考虑职位等。
LBushkin is right, this is not trivial. Since XML is string data you could technically perform a hash of the contents and compare them, but that will be affected by things like whitespace.
You could perform a structured diff (also called 'XML diffgram') between the two documents and compare the results. This is how .NET datasets keep track of changes, for example.
Other than that you'd have to iterate through the DOM and compare elements, attributes and values to each other. If there's a schema involved then you would also have to take into account positions and so on.
通常您想要比较以不同顺序排序的 XML 字符串。使用此代码可以轻松完成此操作
Often You want to compare XML strings ordered differently. This can be done easy with this code