Checking XML for Semantic Equivalence in C#

I was writing a bit of code for a small project and it was creating some XML that I need to pass to another application. So in order to test this functionality, I needed to compare the XML generated by my API against some hard coded XML. I started off with this:


var expectedXml = @"testvalue";

var actualXml = MyAPI.DoSomeStuff().GenerateXml();

Assert.Equal(expectedXml, actualXml);

But I quickly found out that this wasn’t going to scale. Once the XML got too large, it would carry over too far making my tests read horribly. So, I did this:


var expectedXml = @"

testvalue

";

var actualXml = MyAPI.DoSomeStuff().GenerateXml();

Assert.Equal(expectedXml, actualXml);

The problem was that now the XML wasn’t equivalent. Well, it is semantically equivalent, it just isn’t equivalent for a string comparison. The reason for this is that all of that extra white space and EOL characters screws up the comparison. You might be thinking, well, just strip out white space and EOL characters. It ain’t that easy. What happens when that white space is inside of an xml element. Well, at that point it becomes meaningful for comparison purposes.

So I didn’t want to write my own comparison code (who wants to write that?) so I started hunting around. Since I was already using the .NET 3.5 XElement libraries, I started looking there first. I came across a little method on the XNode class called DeepEquals, and guess what, it does exactly what I want. It compares a node and all child nodes for semantic equivalence. I’m sure that there are probably a few gotchas in there for me, but after preliminary tests, it appears to work perfectly.

I created a little method to do my XML asserts for me:


private void AssertEqualXml(string expectedXml, string actualXml)
{
Assert.IsTrue(XNode.DeepEquals(XElement.Parse(expectedXml), XElement.Parse(actualXml)),
String.Format("{0} \n does not equal \n{1}", actualXml, expectedXml));
}

There you have it. It loads the expected and actual XML into XElements and then calls “DeepEquals” on them. Now I can write my XML to compare is the most readable fashion and not worry about how they are going to compare.

Advertisements

4 thoughts on “Checking XML for Semantic Equivalence in C#

  1. Hey Bilal;

    Any reason you didn’t use XML Canonicalization? It’s designed to address just this situation.

    Just curious.

    • You know of an easy way to get a canonical XML format in C#? I’m virtually positive it isn’t in the framework and but I haven’t used any good libraries that will do it. I honestly haven’t spent too much time looking for libraries to do it.

  2. Hey Justin;

    Any reason you didn’t use XML Canonicalization? It’s designed to address just this situation.

    Just curious.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s