Xml Comparison in C#

Xml Comparison in C#

檐上三寸雪 发布于 2021-11-26 字数 922 浏览 745 回复 5 原文

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 Patch C# 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:

XML A:

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

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?

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

旧梦荧光笔 2022-06-07 5 楼

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

The child elements 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.

风为裳 2022-06-07 4 楼

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.

偏爱你一生 2022-06-07 3 楼

I've got an answer by Martin Honnen in 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.

兲鉂ぱ嘚淚 2022-06-07 2 楼

I know that you're focus isn't on unit tests, but XMLUnit can 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.

三岁铭 2022-06-07 1 楼

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

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);
            }
        }
    }
}