Testing for equality

xml files having different ordering of nested elements (author: Rob Nobel)

inSystems XML

Suppose we have to build a service that delivers XML messages and we want to test if the actual messages are indeed equal to what we expect them to be. If the messages are built in a deterministic way (i.e. we are certain that the messages will always be the same) this is a trivial task. However, if for some reason the ordering of elements is not guaranteed, we have to adjust our testing strategy to take the space of possible outcomes into account.

XMLUnit

I’ve done some experimenting with XMLUnit and found out that it helps to overcome this sort of problems quite easily, without much coding. As a first example, let’s consider the following two XML fragments.

inSystems XML

inSystems XML

These two messages are equivalent, except for the two order nodes appearing in reverse order in the second fragment. If we decide that these two messages are in fact to be treated as equal, we have to extend our comparison strategy beyond a basic 1-to-1 comparison. This can be done with XMLUnit by overriding the default node-selecting strategy that is used to compare the two messages. For the above example, a simple unit test could be constructed as follows:

inSystems XML

DiffBuilder

Here, the central object is the DiffBuilder (The builder-pattern is consistently used in the XMLUnit API, allowing for a human readable fluent code style). First we declare the two fragments that should be compared, then we register the namespace(s), and declare that we will ignore comments and whitespace. Next we tell that the actual and expected source should be checked for similarity (as opposed to equality). Thus, by checking for similarity, we explicitely declare that the content of the nodes in the documents are to be the same, but we allow for minor differences to exist, such as the sequencing of sibling elements.

NodeMatcher

By adding a NodeMatcher we can set the strategy for selecting the nodes that are to be compared. Here, we use a DefaultNodeMatcher, with two ElementSelectors. The first ElementSelector is conditional upon element name: if the element name is order, we use a specific ElementSelector, otherwise we fall back to a default ElementSelector.byName (i.e. Elements with the same local name (and namespace URI – if any) can be compared). The custom orderselector uses a selector defined by a Xpath expression, in combination with another ElementSelector with which elements with the same local name (and namespace URI – if any) and attribute values for the given attribute names can be compared. In this way, we declare what uniquely defines an order element : the productdetails child element in combination with the status attribute value.

As a second example, let’s consider the following messages:

inSystems XML

inSystems XML

Here we have 4 order elements, each with a detail element, containing either a status or payment element, both having an employee attribute. Comparing the first and second fragment, we can see that the last two orders are in opposite order in the second fragment. In order to treat these two structures as identical, we need to define a different comparison strategy, illustrated by the following test:

inSystems XML

In this case, the selector is a bit more complex. We now use an and operator, so we can combine two ElementSelectors. The XPath expressions point to the status and payment elements, in combination with the employee attribute. Now we have the correct selecting strategy in place, and these two fragments with different ordering but equal values, will be considered as equivalent.

Of course, a lot more use cases can be made up, and the XMLUnit API has a lot of other functionality. Nevertheless hopefully these two short examples can help you make a quickstart while tackling these sort of challenges.

Share this

Contact

Heb je vragen of opmerkingen? Aarzel niet om contact op te nemen. Dat kan via de algemene contactgegevens, rechtstreeks met de genoemde contactpersoon op een van de detailpagina’s, of via onderstaande knop.

29 juni 2026

Welke midlance regeling past bij mij?

Medium-lance / Midlance wint snel aan populariteit. Het combineert de zekerheid van een vast dienstverband met de mogelijkheid om een aanzienlijk hoger inkomen te verdienen wanneer je op mooie opdrachten wordt ingezet.

18 juni 2026

AI inspiratiesessie

AI is nauwelijks nog weg te denken uit het nieuws. Vrijwel dagelijks verschijnen er berichten over nieuwe AI-toepassingen. Dat roept vragen op. Wat is AI eigenlijk precies? Wat kunnen deze systemen wel en niet? Wat betekent dit voor mij?

Opdrachten uitgevoerd voor

ING Bank
PC Uitvaart
Telegraaf Media Groep
Rabobank
RAVU
BMW
WVDB Adviseurs Accountants
Ahold
MN Services
Bank Mendes Gans
NVWA inSystems
Greenchoice
TenneT
SVB
Rijk Zwaan inSystems
VTTI
Alphabet
VAA ICT Consultancy
Rendo
Altran
Multi Tank Card
AgroEnergy
Oracle University
Darling
Van Iperen Groeispecialisten
Provincie Utrecht
GVB
CBR
Rechtspraak
Nederlandse Spoorwegen
ASR Nederland
Eneco
Alliance Healthcare
JUVA
Syntrus Achmea Real Estate & Finance
DICTU
inSystems Unive
Gemeente Gouda
Holland Casino
Thales
inSystems KLM
Universiteit Tilburg
Twinq
TU Eindhoven
Stratech Social
Feenstra inSystems
Leaseplan
Fokker
IBM
Cannock
RIGD LOXIA
Arval BNP Paribas
UBR Uitvoeringsorganisatie Bedrijfsvoering Rijk
CB Logistics
VION Food Group
Ministerie van Economische Zaken, Landbouw & Innovatie
Belastingdienst
Stedin
Allianz
Ziggo
Politie
Gemeente Den Haag
Gemeente Apeldoorn