C#中的XML比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/794331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:26:48  来源:igfitidea点击:

Xml Comparison in C#

c#xml

提问by Yaron Naveh

I'm trying to compare two Xml files using C# code. I want to ignore Xml syntax differences (i.e. prefix names). For that I am using Microsoft's XML Diff and PatchC# API. It works for some Xml's but I couldn't find a way to configure it to work with the following two Xml's:

我正在尝试使用 C# 代码比较两个 Xml 文件。我想忽略 Xml 语法差异(即前缀名称)。为此,我正在使用 Microsoft 的XML Diff 和 PatchC# API。它适用于某些 Xml,但我找不到将其配置为使用以下两个 Xml 的方法:

XML A:

XML A:

<root xmlns:ns="http://myNs">
  <ns:child>1</ns:child>
</root>

XML B:

XML B:

<root>
  <child xmlns="http://myNs">1</child>
</root>

My questions are:

我的问题是:

  1. Am I right that these two xml's are semantically equal (or isomorphic)?
  2. Can Microsoft's XML Diff and Patch API be configured to support it?
  3. Are there any other C# utilities to to this?
  1. 这两个xml在语义上相等(或同构)是否正确?
  2. 可以配置 Microsoft 的 XML Diff 和 Patch API 以支持它吗?
  3. 是否还有其他 C# 实用程序可以用于此目的?

采纳答案by Yaron Naveh

I've got an answer by Martin Honnenin XML and the .NET Framework MSDN Forum. In short he suggests to use XQuery 1.0's deep-equal function and supplies some C# implementations. Seems to work.

我在 XML 和 .NET Framework MSDN 论坛中得到了 Martin Honnen 的回答。简而言之,他建议使用 XQuery 1.0 的 deep-equal 函数并提供一些 C# 实现。似乎工作。

回答by rguerreiro

I know that you're focus isn't on unit tests, but XMLUnitcan compare two XML files and I think it's able to solve your example. Maybe you could look at the code ahd figure out your solution.

我知道您关注的不是单元测试,但XMLUnit可以比较两个 XML 文件,我认为它能够解决您的示例。也许您可以查看代码以找出您的解决方案。

回答by Neil Barnwell

It might be an idea to load XmlDocument instances from each xml file, and compare the XML DOM instead? Providing the correct validation is done on each, that should give you a common ground for a comparison, and should allow standard difference reporting. Possibly even the ability to update one from the other with the delta.

从每个 xml 文件加载 XmlDocument 实例并比较 XML DOM 可能是一个想法?提供对每个都进行了正确的验证,这应该为您提供一个比较的共同点,并且应该允许标准差异报告。甚至可能能够使用增量从另一个更新一个。

回答by Robert Rossney

Those documents aren't semantically equivalent. The top-level element of the first is in the http://myNSnamespace, while the top-level element of the second is in the default namespace.

这些文档在语义上不是等价的。第一个的顶级元素在http://myNS命名空间中,而第二个的顶级元素在默认命名空间中。

The childelements of the two documents are equivalent. But the documents themselves aren't.

两个文档的元素是等价的。但文件本身不是。

Edit:

编辑:

There's a world of difference between xmls:ns='http://myNS'and xmlns='http://myNS', which I appear to have overlooked. Anyway, those documents are semantically equivalent and I'm just mistaken.

xmls:ns='http://myNS'和之间存在天壤之别xmlns='http://myNS',我似乎忽略了这一点。无论如何,这些文档在语义上是等效的,我只是弄错了。

回答by Ronald Wildenberg

The documents are isomorphic as can be shown by the program below. I think if you use XmlDiffOptions.IgnoreNamespacesand XmlDiffOptions.IgnorePrefixesto configure Microsoft.XmlDiffPatch.XmlDiff, you get the result you want.

这些文档是同构的,如下面的程序所示。我认为如果你使用XmlDiffOptions.IgnoreNamespacesandXmlDiffOptions.IgnorePrefixes来配置Microsoft.XmlDiffPatch.XmlDiff,你会得到你想要的结果。

using System.Linq;
using System.Xml.Linq;
namespace SO_794331
{
    class Program
    {
        static void Main(string[] args)
        {
            var docA = XDocument.Parse(
                @"<root xmlns:ns=""http://myNs""><ns:child>1</ns:child></root>");
            var docB = XDocument.Parse(
                @"<root><child xmlns=""http://myNs"">1</child></root>");

            var rootNameA = docA.Root.Name;
            var rootNameB = docB.Root.Name;
            var equalRootNames = rootNameB.Equals(rootNameA);

            var descendantsA = docA.Root.Descendants();
            var descendantsB = docB.Root.Descendants();
            for (int i = 0; i < descendantsA.Count(); i++)
            {
                var descendantA = descendantsA.ElementAt(i);
                var descendantB = descendantsB.ElementAt(i);
                var equalChildNames = descendantA.Name.Equals(descendantB.Name);

                var valueA = descendantA.Value;
                var valueB = descendantB.Value;
                var equalValues = valueA.Equals(valueB);
            }
        }
    }
}