Как игнорировать некоторые элементы при сравнении XML?
У меня есть XML-сообщение:
<root>
<elementA>something</elementA>
<elementB>something else</elementB>
<elementC>yet another thing</elementC>
</root>
Я хочу сравнить сообщение этого типа, созданное методом тестирования с ожидаемым сообщением, но меня не волнует elementA
. Итак, я хотел бы, чтобы приведенное выше сообщение считалось равным:
<root>
<elementA>something different</elementA>
<elementB>something else</elementB>
<elementC>yet another thing</elementC>
</root>
Я использую последнюю версию XMLUnit.
Я предполагаю, что ответ включает создание пользовательского DifferenceListener
; Я просто не хочу изобретать велосипед, если там что-то готово для использования там.
Приветствуются предложения, которые используют библиотеку, отличную от XMLUnit.
Ответы
Ответ 1
Все изменилось для XMLUnit, так как на этот вопрос был дан ответ.
Теперь вы можете легко игнорировать node при использовании DiffBuilder
:
final Diff documentDiff = DiffBuilder
.compare(expectedSource)
.withTest(actualSource)
.withNodeFilter(node -> !node.getNodeName().equals(someName))
.build();
Если вы затем вызываете documentDiff.hasDifferences()
, то узлы, добавленные в фильтр, будут игнорироваться.
Ответ 2
Я завершил реализацию DifferenceListener
, который принимает список имен node (с пространствами имен), чтобы игнорировать текстовые отличия для:
public class IgnoreNamedElementsDifferenceListener implements DifferenceListener {
private Set<String> blackList = new HashSet<String>();
public IgnoreNamedElementsDifferenceListener(String ... elementNames) {
for (String name : elementNames) {
blackList.add(name);
}
}
public int differenceFound(Difference difference) {
if (difference.getId() == DifferenceConstants.TEXT_VALUE_ID) {
if (blackList.contains(difference.getControlNodeDetail().getNode().getParentNode().getNodeName())) {
return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
}
return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
}
public void skippedComparison(Node node, Node node1) {
}
}
Ответ 3
Я бы использовал XSLT и преобразование идентичности, чтобы отфильтровать элементы, которые я хочу игнорировать, и сравнить результаты.
См. XSL: как скопировать дерево, но удалить некоторые узлы? ранее на SO.
Ответ 4
Открытый класс IgnoreNamedElementsDifferenceListener реализует DifferenceListener { private Set blackList = new HashSet();
public IgnoreNamedElementsDifferenceListener(String ... elementNames) {
for (String name : elementNames) {
blackList.add(name);
}
}
public int differenceFound(Difference difference) {
if (difference.getId() == DifferenceConstants.TEXT_VALUE_ID) {
if (blackList.contains(difference.getControlNodeDetail().getNode().getParentNode().getNodeName())) {
return DifferenceListener.RETURN_IGNORE_DIFFERENCE_NODES_IDENTICAL;
}
}
return DifferenceListener.RETURN_ACCEPT_DIFFERENCE;
}
public void skippedComparison(Node node, Node node1) {
}
}
Как вызвать эту собственную реализацию для моего метода, чтобы увидеть различия после того, как конкретный node проигнорирован для сравнения.?