The following code compares two XML texts and returns a collection of data changes between them.
This code works fine but needs to be as resource-friendly as possible.
Is there a faster way to do this in LINQ, e.g. without creating the two collections of XElements and comparing each of their fields for differences?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace TestXmlDiff8822
{
class Program
{
static void Main(string[] args)
{
XDocument xdoc1 = XDocument.Parse(GetXml1());
XDocument xdoc2 = XDocument.Parse(GetXml2());
List<HistoryFieldChange> hfcList = GetHistoryFieldChanges(xdoc1, xdoc2);
foreach (var hfc in hfcList)
{
Console.WriteLine("{0}: from {1} to {2}", hfc.FieldName, hfc.ValueBefore, hfc.ValueAfter);
}
Console.ReadLine();
}
static public List<HistoryFieldChange> GetHistoryFieldChanges(XDocument xdoc1, XDocument xdoc2)
{
List<HistoryFieldChange> hfcList = new List<HistoryFieldChange>();
var elements1 = from e in xdoc1.Root.Elements()
select e;
var elements2 = from e in xdoc2.Root.Elements()
select e;
for (int i = 0; i < elements1.Count(); i++)
{
XElement element1 = elements1.ElementAt(i);
XElement element2 = elements2.ElementAt(i);
if (element1.Value != element2.Value)
{
HistoryFieldChange hfc = new HistoryFieldChange();
hfc.EntityName = xdoc1.Root.Name.ToString();
hfc.FieldName = element1.Name.ToString();
hfc.KindOfChange = "fieldDataChange";
hfc.ObjectReference = (xdoc1.Descendants("Id").FirstOrDefault()).Value;
hfc.ValueBefore = element1.Value;
hfc.ValueAfter = element2.Value;
hfcList.Add(hfc);
}
}
return hfcList;
}
public static string GetXml1()
{
return @"
<Customer>
<Id>111</Id>
<FirstName>Sue</FirstName>
<LastName>Smith</LastName>
</Customer>
";
}
public static string GetXml2()
{
return @"
<Customer>
<Id>111</Id>
<FirstName>Sue2</FirstName>
<LastName>Smith-Thompson</LastName>
</Customer>
";
}
}
public class HistoryFieldChange
{
public string EntityName { get; set; }
public string FieldName { get; set; }
public string ObjectReference { get; set; }
public string KindOfChange { get; set; }
public string ValueBefore { get; set; }
public string ValueAfter { get; set; }
}
}