Skip to content

Instantly share code, notes, and snippets.

@krcourville
Last active December 25, 2015 06:39
Show Gist options
  • Select an option

  • Save krcourville/6933451 to your computer and use it in GitHub Desktop.

Select an option

Save krcourville/6933451 to your computer and use it in GitHub Desktop.
Element-centric XML diff with Linq to Xml
void Main()
{
var contact = new Contact{
FirstName = "John",
LastName = "Smith",
HomePhone = new Phone{
Number = "303-123-1234"
}
};
var doc1 = ToXDocument(contact);
contact.LastName = "Changed";
var doc2 = ToXDocument(contact);
var differences = doc2.Descendants("Contact").Except(doc1.Descendants("Contact"), new Comparer());
differences.Dump();
foreach (XNode d in differences)
{
var el = d as XElement;
el.Name.Dump("Name");
el.Value.Dump("Value");
}
}
class Comparer : IEqualityComparer<XNode>
{
public bool Equals(XNode e1, XNode e2){
if( !(e1 is XElement)) return true;
if( !(e2 is XElement)) return false;
var el1 = e1 as XElement;
var el2 = e2 as XElement;
return Tuple.Create(el1.Name,el1.Value).Equals(Tuple.Create(el2.Name,el2.Value));
}
public int GetHashCode(XNode n){
if( !(n is XElement)) return 0;
var el = n as XElement;
return Tuple.Create(el.Name,el.Value).GetHashCode();
}
}
XDocument ToXDocument<T>(T o){
return XDocument.Parse(ToXml(o));
}
string ToXml<T>(T o){
var serializer = new XmlSerializer(typeof(T));
var writer = new StringWriter();
serializer.Serialize(writer,o);
return writer.ToString();
}
public class Contact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Phone HomePhone { get; set; }
}
public class Phone {
public string Number { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment