How to Ignore Certain Elements When Comparing Xml

How do I ignore certain elements when comparing XML?

Things have changed a lot for XMLUnit since this question was answered.

You can now easily ignore a node when using a DiffBuilder:

final Diff documentDiff = DiffBuilder
.compare(expectedSource)
.withTest(actualSource)
.withNodeFilter(node -> !node.getNodeName().equals(someName))
.build();

If you then call documentDiff.hasDifferences() nodes added to filter will be ignored.

XMLUNIT How do I ignore multiple elements when comparing XML?

You can just use logic operators, for example,

.withNodeFilter(node -> !(node.getNodeName().equals("metadata") ||
node.getNodeName().equals("comment"))

This will match all nodes which are not metadata or comment.

Compare two xml files ignoring certain elements using XPath in Java

You need to transform both files into a form where they compare equal, by removing the elements you want to ignore. You would typically do this using XSLT. After the transformation you could either compare the results using the XPath 2.0 function deep-equal(), or serialise both documents as canonical XML and compare the files at the character or binary level.

I would do this by running XQuery Update to delete the nodes selected by the path expression, and then comparing the resulting documents either using fn:deep-equal(), or by doing canonical serialization and comparing the resulting lexical forms.

As an alternative to XQuery Update you could use xmlstarlet or Saxon's Gizmo tool.

But it might depend on what you want from the comparison. The above is fine if you want a yes/no answer, but getting details of the differences is more difficult. You could write your own query to find the differences, or use a tool such as DeltaXML.

NOTE: This answer has been subsequently edited by a third party in a way that makes nonsense of the comment thread. Please ignore the comments.

Ignoring a particular attribute of a specific Node while comparing xml files using XMLUnit 2.X

You could use a DifferenceEvaluator if you really wanted to. All you'd have to do was testing the name of the Attr's "owner element"'s name in addition to the name of the attribute itself.

But XMLUnit 2.x offers a different solution to this: AttributeFilter. The code won't be that different from the DifferenceEvaluator you've already got, but you won't be mixing concerns.

class IgnoreNoteId implements Predicate<Attr> {

public boolean test(Attr attr) {
return !("note".equals(attr.getOwnerElement().getNodeName())
&& "id".equals(attr.getNodeName()));
}
}

or even shorter with a lambda in withAttributeFilter when using Java8.

Does XMLUNIT provide option to ignore certain elements in XML's for comparison?

I'm afraid a custom DifferenceListener is the only way to go right now. There is a feature request for XMLUnit2 (https://github.com/xmlunit/xmlunit/issues/26) that hasn't been implemented, yet.

Implementing the DifferenceListener may be a bit cumbersome since you'll not only receive Differences for the elements you want to ignore but most likely also receive them for the number of children of the parent element.

Each Difference contains NodeDetails for the nodes seen on the test and control side and the NodeDetail contains the DOM Node (which will be an Element in your case).

XmlUnit ignore order of elements when comparing XML files

I don't see any nested text inside your price-table elements at all, so byNamAndText matches on element names only - which will be the same for all price-tables and thus not do what you want.

In you example there is no ambiguity for price-tables as there is only one anyway. So the byXPath approach looks wrong. At least in your snippet XMLUnit should do fine with byName except for the price-table elements.

I'm not sure whether product-id alone is what identifies your price-table elements or the combination of all attributes. Either byNameAndAttributes("product-id") or its byNameAndAllAttributes cousin should work.

If it is only product-id then byNameAndAttributes("product-id") becomes byName for all elements that don't have any product-id attribute at all. In this special case byNameAndAttribute("product-id") alone will work for your whole document as we can see it - more or less by accident.

If you need more complex rules for other elements than price-table or you want to make things more explicit than

ElementSelectors.conditionalBuilder()
.whenElementIsNamed("price-table")
.thenUse(ElementSelectors.byNameAndAttributes("product-id"))
// more special cases
.elseUse(ElementSelectors.byName)

is the better choice.

XMLUnit-2 ignore certain nested XML elements

Neither "accountFlags" nor "homePhone" are element names, so my filter will not match anything.

The NodeFilter must return true unless all of the following conditions are met

  • node is actually an Element
  • node has an attribute named "key"
  • the value of this attribute is either "accountFralgs" or "homePhone"
    private boolean filter(final Node n) {
if (n instanceof Element) {
final String attrValue = ((Element) n).getAttibute("key");
// attrValue is th eempty string if the attribute is missing
return !("accountFlags".equals(attrValue) || "homePhone".equals(attrValue));
}
return true;
}

How to ignore nodes with It values when comparing two xmls with XMLUnit2

Found solution for first part of the above question

diff = DiffBuilder.compare(ResXML1).withTest(ResXML2)
.withNodeMatcher(
new DefaultNodeMatcher(
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("ShiftAttribute")
.thenUse( ElementSelectors.byNameAndAttributes("ShiftAttributeCode"))
.elseUse(ElementSelectors.byName)
.build()
)
).build();


Related Topics



Leave a reply



Submit