c# compare to xml files to find the difference

vcurtis
vcurtis used Ask the Experts™
on
Hello
  I have two xml files and I want to print the difference between  the two (finding the updates). Has anyone done this before? Does anyone have a script they care to share
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
How detailed are you trying to go? Are you going to compare elements by namespace as well, or is this just more of a textual comparison? If the latter, why not just download a file compare utility and invoke it via the Process class?

Author

Commented:
First, thank you for taking the time

I want to compare elements. I have name address phone city and state for each. I need to compare yesterdays files with today and identify when one has been updated.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Understood, but are namespaces involved? Is it possible to post an example of the XML, and maybe the schema (if one is defined)?
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Author

Commented:
Requested file uploaded.
Members.xml
anarki_jimbelSenior Developer

Commented:
I believe käµfm³d's suggestion about textual comparison is OK for such files.

However, I'd write a utility that compares element (text nodes) values. This should be pretty straightforward.
We went this way (some years ago) when we had to compare pretty big and rather complex xml files.

Author

Commented:
Yes, I get the idea. Just do not know how it is done. Was hoping to  get some assistance. I am new to this and the boss is acting like I have been  doing it for years
anarki_jimbelSenior Developer
Commented:
In meantime look at this:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/fa015b1a-178f-4676-acc8-ab1204cd7857/find-difference-between-two-xmls-of-same-structure?forum=csharpgeneral

I can't remember exactly how we did but let me think how can we do this in assumption that the structure of both xml files is same.

I'm thinking we may use XNode.DeepEquals (https://msdn.microsoft.com/en-us/library/bb336169(v=vs.110).aspx). However you need to be a bit familiar to LINQ.
Fernando SotoRetired
Distinguished Expert 2017

Commented:
Can you post the schema of the XML as well an actual copy of the XML file.
Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015
Commented:
So one approach would be a recursive function. This particular approach is more old school, relying on XML document rather than LINQ-to-XML, but the latter is just as feasible to use. The approach basically recurses down the document dept-first--meaning it will try to go as deep into a node's children as possible prior to going to a sibling node. The recursion happens in line 44, where the function calls itself. It does this if the function detects that you are on a node which has children. Otherwise, you simply compare the values of the two nodes. There is some preliminary checking for structural differences. Finally, there is a recursive function to build the XPath of any offending nodes, for ease of reporting.

This is a quick-and-dirty example. You could certainly tweak it to your environment. I also didn't do extensive error checking, so there could be bugs. The others may be able to show you a LINQ-to-XML approach that might be shorter.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace _28920881
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlDocument yesterday = new XmlDocument();
            XmlDocument today = new XmlDocument();

            yesterday.Load("yesterday.xml");
            today.Load("today.xml");

            string errorMessage = CompareXml(yesterday, today);

            Console.WriteLine(errorMessage);

            Console.ReadKey();
        }

        private static string CompareXml(XmlNode yesterday, XmlNode today)
        {
            string errorMessage = string.Empty;

            if (yesterday.Name != today.Name)
            {
                errorMessage = $"Mismatched node name: {GetXPath(yesterday)} vs. {GetXPath(today)}";
            }
            else if ((yesterday.HasChildNodes && !today.HasChildNodes) || (!yesterday.HasChildNodes && today.HasChildNodes))
            {
                errorMessage = $"Mismatched node structure: {GetXPath(yesterday)} vs. {GetXPath(today)}";
            }
            else if (yesterday.HasChildNodes && today.HasChildNodes)
            {
                IEnumerator<XmlNode> yIterator = yesterday.ChildNodes.OfType<XmlNode>().GetEnumerator();
                IEnumerator<XmlNode> tIterator = today.ChildNodes.OfType<XmlNode>().GetEnumerator();

                while (yIterator.MoveNext() && tIterator.MoveNext())
                {
                    errorMessage = CompareXml(yIterator.Current, tIterator.Current);

                    if (errorMessage.Length > 0) break;
                }

                yIterator.Dispose();
                tIterator.Dispose();
            }
            else if (yesterday.InnerText != today.InnerText)
            {
                errorMessage = $"Mismatched node values: {GetXPath(yesterday)} vs. {GetXPath(today)}";
            }

            return errorMessage;
        }

        private static string GetXPath(XmlNode node)
        {
            if (node == null)
            {
                return string.Empty;
            }
            else if (node.NodeType == XmlNodeType.Text)
            {
                return GetXPath(node.ParentNode);
            }
            else if (node.ParentNode != null && node.ParentNode != node.OwnerDocument)
            {
                return $"{GetXPath(node.ParentNode)}/{node.Name}";
            }
            else
            {
                return $"/{node.Name}";
            }
        }
    }
}

Open in new window

Author

Commented:
Thank you so much, you just made me the hero of my company " Until the next problem comes up that is"

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial