我有一条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以外的库的建议。
答案 0 :(得分:38)
我最终实现了一个DifferenceListener
,其中包含一个节点名称列表(带有名称空间),以忽略以下内容的文本差异:
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) {
}
}
答案 1 :(得分:15)
由于这个问题得到了回答,XMLUnit的情况发生了很大的变化。
现在,您可以在使用DiffBuilder
时轻松忽略节点:
final Diff documentDiff = DiffBuilder
.compare(expectedSource)
.withTest(actualSource)
.withNodeFilter(node -> !node.getNodeName().equals(someName))
.build();
如果您再调用documentDiff.hasDifferences()
,则会忽略添加到过滤器的节点。
答案 2 :(得分:8)
我会使用XSLT和identity transform过滤掉我想忽略的元素,并比较结果。
答案 3 :(得分:0)
您现在可以在XMLUnit 2.6.0中尝试${xmlunit.ignore}
(添加依赖项xmlunit-placeholders)。示例代码如下。
Diff diff = DiffBuilder
.compare(expectedXML)
.withTest(actualXML)
.withDifferenceEvaluator(new PlaceholderDifferenceEvaluator())
.build();
期望的XML:
<root>
<elementA>${xmlunit.ignore}</elementA>
<elementB>something else</elementB>
<elementC>yet another thing</elementC>
</root>
实际XML:
<root>
<elementA>anything</elementA>
<elementB>something else</elementB>
<elementC>yet another thing</elementC>
</root>
请注意,从unit tests可以看出,目前$ {xmlunit.ignore}仅支持文本节点和属性值无知。
答案 4 :(得分:0)
让我们简单一点,忽略节点,无论您要忽略多少个节点,或者如果您不知道要忽略多少个节点 ,请按照以下简单步骤操作
这只是一个 XMLdiff 方法,将两个 xml 作为字符串
public static void XMLdiff(String XML1, String XML2){
//nodes you wanted to ignore
String[] ignoreNodes = {"nodeX", "nodeY", "nodeZ"};
//testnode(node,ignoreNodes) is handled below for finding and ignoring multiple nodes
final Diff documentDiff = DiffBuilder.compare(XML1)
.withTest(XML2)
.withNodeFilter(node->testnode(node,ignoreNodes))
.build();
}
private static boolean testnode(Node node, String[] name) {
for (int i = 0; i < name.length; i++) {
if (node.getNodeName().toString().equals(name[i])) {
return false;
}
if (name.length == 0) {
break;
}
}
return true;
}
从此链接添加依赖项或 jar https://www.xmlunit.org/
答案 5 :(得分:-1)
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) {
}
}
如何在我的方法中调用这个自己的实现,以便在比较后忽略特定节点后查看差异。?