tags:

views:

2678

answers:

5

Hi

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"&gt;
  <ns:child>1</ns:child>
</root>

XML B:

<root>
  <child xmlns="http://myNs"&gt;1&lt;/child&gt;
</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  A: 

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.

Rodrigo Guerreiro
Actually my focus is on unit tests.However XMLUnit also seems to have similar limitations in .Net. It actually worked for the Xml's above but a slight variation broke it.
Yaron Naveh
+1  A: 

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.

Neil Barnwell
It's an option - but it's doing by myself something which I believe to be a common problem with a common solution.
Yaron Naveh
+1  A: 

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.

Robert Rossney
That's incorrect. The top-level elements of both documents are in the default namespace. The top-level element of the first document can only be in the http://myNs namespace if it is declared either as<ns:root xmlns:ns="http://myNs">or<root xmlns="http://myNs">
Ronald Wildenberg
+2  A: 

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""&gt;&lt;ns:child&gt;1&lt;/ns:child&gt;&lt;/root&gt;");
            var docB = XDocument.Parse(
                @"<root><child xmlns=""http://myNs""&gt;1&lt;/child&gt;&lt;/root&gt;");

            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 = descendantA.Value;
                var equalValues = valueA.Equals(valueB);
            }
        }
    }
}
Ronald Wildenberg
IgnoreNamespaces is not good for me - I consider documents with different namespaces to be different semantically.
Yaron Naveh
Ronald Wildenberg
A and B in my previous comment were meant to be two urls but they were converted to links...
Ronald Wildenberg
When I try it I get that they're equal
Yaron Naveh
I get the same result you get. I think I made a mistake before. Continuing the investigation...
Ronald Wildenberg
I posted an issue on Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=437072. I do not see any other explanation than that it's a bug.
Ronald Wildenberg
They have escalated the issue, so it seems to be a real bug: 'We are escalating this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue'
Ronald Wildenberg
+1  A: 

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.

Yaron Naveh