Easy way to compare two XMLs for equality
The first thing to do is normalize to two XMLs, for this you can use a small method using Linq:
private static XElement Normalize(XElement element)
{
if (element.HasElements)
{
return new XElement(
element.Name,
element.Attributes().Where(a => a.Name.Namespace == XNamespace.Xmlns)
.OrderBy(a => a.Name.ToString()),
element.Elements().OrderBy(a => a.Name.ToString())
.Select(e => Normalize(e)));
}
if (element.IsEmpty)
{
return new XElement(element.Name, element.Attributes()
.OrderBy(a => a.Name.ToString()));
}
return new XElement(element.Name, element.Attributes()
.OrderBy(a => a.Name.ToString()), element.Value);
}
After both elements were normalized, simply you can compare both strings:
bool equal = Normalize(expected).ToString() ==
Normalize(actual).ToString();
A nice place to use this is in unit tests, where you can do your own XML assert class:
public static class XmlAssert
{
public static void AreEqual(
XElement expected,
XElement actual)
{
Assert.AreEqual(
Normalize(expected).ToString(),
Normalize(actual).ToString());
}
private static XElement Normalize(XElement element)
{
if (element.HasElements)
{
return new XElement(
element.Name,
element.Attributes()
.OrderBy(a => a.Name.ToString()),
element.Elements()
.OrderBy(a => a.Name.ToString())
.Select(e => Normalize(e)));
}
if (element.IsEmpty)
{
return new XElement(
element.Name,
element.Attributes()
.OrderBy(a => a.Name.ToString()));
}
return new XElement(element.Name, element.Attributes()
.OrderBy(a => a.Name.ToString()), element.Value);
}
}