XMLUnit with Java 9 and above - xmlunit/user-guide GitHub Wiki
This page gathers the things that you need to know if you want to run XMLUnit apps on Java 9 and above.
With Java 9 the Transformer class behavior is different from previous versions.
Let's see it with and example:
<?xml version="1.0" encoding="UTF-8"?>
<notification>
<to>[email protected]</to>
<info><![CDATA[update]]></info>
</notification>
And store in a input
String
variable. To process with the transformer:
StreamSource source = new StreamSource(new StringReader(input));
Transformer transformer = TransformerFactory
.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
String output = result
.getWriter()
.toString();
If we tried to compare using xmlunit-assertj areSimilar()
function:
assertThat(input)
.and(output)
.areSimilar();
In Java 8 it will pass, but with Java 9 and above we'll get the following differences:
java.lang.AssertionError:
Expecting:
<<notification>
<to>[email protected]</to>
<info><![CDATA[update]]></info>
</notification>>
to be equal to:
<<notification>
␣␣␣␣␣␣␣␣
<to>[email protected]</to>
␣␣␣␣␣␣␣␣
<info>
␣␣␣␣␣␣␣␣<![CDATA[update]]>
</info>
␣␣␣␣
</notification>>
but was not.
- Extra newlines with spaces between elements.
- The elements with CDATA are in new lines with spaces. (This issue has been fixed in Java 14. Tested it with the 14-ea+6-171 build)
Both cases are known issues related to the changes in the JDK. We can found more details here https://github.com/CodeFX-org/java-9-wtf/tree/master/xml-transformer, https://stackoverflow.com/questions/55853220/handling-change-in-newlines-by-xml-transformation-for-cdata-from-java-8-to-java, and https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8223291.
In order to mitigate them, we can use the replaceAll()
function with a regex:
- To remove the additional new lines:
output.replaceAll("(?m)^[ \t]*\r?\n", "");
- To remove the newline between the CDATA tag:
xml.replaceAll(">\\s*(<\\!\\[CDATA\\[.*?]]>)\\s*</", ">$1</");