New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XMLUnit 2 API to specify XSD for similarity for ATTR_VALUE_EXPLICITLY_SPECIFIED #88
Comments
To be honest, I don't really know whether it is possible. XMLUnit uses https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Attr.html#getSpecified() to know whether the attribute has been specified explicitly. I'm not really sure what needs to be done to make the XML parser add the implicit values of attributes from a schema. You may want to play with something like https://xerces.apache.org/xerces2-j/faq-pcfp.html#faq-4 and compare I'm absolutely open to modifying the API in order to make the process easier once we know what exactly is involved. |
Thank you for the feedback. Okay, so for the moment I'm using a custom Set<QName> attrWhichCanDefault = new HashSet<QName>();
attrWhichCanDefault.addAll(Arrays.asList(new QName[] {
new QName("attr1"),
new QName("attr2"),
new QName("attr3")
}));
Set<String> nodeHavingDefaultableAttr = new HashSet<>();
nodeHavingDefaultableAttr.addAll(Arrays.asList(new String[]{"elemA", "elemB"}));
Diff checkSimilar = DiffBuilder
.compare( control )
.withTest( test )
.withDifferenceEvaluator(
DifferenceEvaluators.chain(DifferenceEvaluators.Default,
((comparison, outcome) -> {
if (outcome == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.ELEMENT_NUM_ATTRIBUTES) {
if (comparison.getControlDetails().getTarget().getNodeName().equals( comparison.getTestDetails().getTarget().getNodeName() )
&& nodeHavingDefaultableAttr.contains( comparison.getControlDetails().getTarget().getNodeName() )) {
return ComparisonResult.SIMILAR;
}
}
if (outcome == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.ATTR_NAME_LOOKUP) {
boolean testIsDefaulableAttribute = false;
QName whichDefaultableAttr = null;
if (comparison.getControlDetails().getValue() == null && attrWhichCanDefault.contains(comparison.getTestDetails().getValue())) {
for (QName a : attrWhichCanDefault) {
boolean check = comparison.getTestDetails().getXPath().endsWith("@"+a);
if (check) {
testIsDefaulableAttribute = true;
whichDefaultableAttr = a;
continue;
}
}
}
if ( testIsDefaulableAttribute ) {
if (comparison.getTestDetails().getXPath().equals(comparison.getControlDetails().getXPath() + "/@" + whichDefaultableAttr )) {
return ComparisonResult.SIMILAR;
}
}
}
return outcome;
})))
.ignoreWhitespace()
.checkForSimilar()
.build();
assertFalse("XML are NOT similar: " + checkSimilar.toString(), checkSimilar.hasDifferences()); However the code is far from being complete:
For the use case I'm using this code, it should not impact so safe, but I thought helpful to draft how I'm currently trying to approach the problem differently. Thank you for the pointers about how xmlunit expects be notified about optional attributes, I'll try to dig further also in that direction! |
Your approach will certainly work but a generalized solution would require somebody to parse and understand XML Schema. I prefer this "somebody" to be the XML parser :-) I'll be very interested in your results. |
I have a similar use case where two documents are considered different, but they only differ in the default value explicitly given. I therefore like to know if something has changed here? From the API I would expect something like |
no, I am not aware of anybody working on this. The main problem is that the solution requires something to read the XML Schema and understand it well enough to expose the default values for attributes. Right now XMLUnit doesn't contain any code that would understand XML Schema, it purely relies on the JAXP XML parser to do so when validating, for example. |
I see, would it be an option to specify default values for an attribute manually? e.g. something like
if that is available one might later on enhance this to extract the data from the XSD... |
If you know this upfront exactly enough to specify the default value, then you would probably be able to write a What you describe would certainly be possible, but not without adding new ways to extend the It can certainly be done but it would only be useful in a pretty rare situation where (a) you rely on default attribute values and (b) are willing to list them all explicitly once again in addition to the schema. You may be willing to do so, but I doubt many other people are :-) |
Hello, I'm trying to compare two XML documents for which "control" implies a default attribute, while "test" make the attribute explicit with default value.
I have noted the
DifferenceEvaluators.Default
specifies forComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED
the outcome is indeedComparisonResult.SIMILAR
as I would expected.However I'm unable to obtain the desired output while using XMLUnit 2 API, as it does not appear to be a way to specify the XSD schema where this definition (attribute is optional with default value) is actually specified.
This is my XSD:
This is "control" xml which implies a default attribute:
This is "test" xml where the attribute is explicit with default value:
I would have expected if I XMLUnit Diff-them, they should be "similar", but result actually is "different".
Here is snippet my JUnit test inlined for convenience:
Both XML file validate against the XSD Schema, however test fails with result "different".
I've also checked with included JUnit test suite of XMLUnit, but the only relevant test case I found is
DefaultComparisonFormatterTest.testComparisonType_ATTR_VALUE_EXPLICITLY_SPECIFIED()
here: https://github.com/xmlunit/xmlunit/blob/master/xmlunit-core/src/test/java/org/xmlunit/diff/DefaultComparisonFormatterTest.java#L409however this test is using DTD.
Is it possible to achieve the same result instead of DTD by using the XSD schema as described above, please?
ps: thank you for XMLUnit is great ! =)
The text was updated successfully, but these errors were encountered: