比较两个忽略元素顺序的 XML 字符串 [英] Compare two XML strings ignoring element order
问题描述
假设我有两个 xml 字符串
Suppose I have two xml strings
<test>
<elem>a</elem>
<elem>b</elem>
</test>
<test>
<elem>b</elem>
<elem>a</elem>
</test>
如何编写一个测试来比较这两个字符串并忽略元素顺序?
How to write a test that compares those two strings and ignores the element order?
我希望测试尽可能短,没有地方进行 10 行 XML 解析等.我正在寻找一个简单的断言或类似的东西.
I want the test to be as short as possible, no place for 10-line XML parsing etc. I'm looking for a simple assertion or something similar.
我有这个(不起作用)
Diff diff = XMLUnit.compareXML(expectedString, actualString);
XMLAssert.assertXMLEqual("meh", diff, true);
推荐答案
我原来的回答已经过时了.如果我必须再次构建它,我将使用 xmlunit 2 和 xmlunit-matchers.请注意,对于 xml 单元,不同的顺序总是相似"不等于.
My original answer is outdated. If I would have to build it again i would use xmlunit 2 and xmlunit-matchers. Please note that for xml unit a different order is always 'similar' not equals.
@Test
public void testXmlUnit() {
String myControlXML = "<test><elem>a</elem><elem>b</elem></test>";
String expected = "<test><elem>b</elem><elem>a</elem></test>";
assertThat(myControlXML, isSimilarTo(expected)
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
//In case you wan't to ignore whitespaces add ignoreWhitespace().normalizeWhitespace()
assertThat(myControlXML, isSimilarTo(expected)
.ignoreWhitespace()
.normalizeWhitespace()
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText)));
}
如果有人仍然不想在这里使用纯 Java 实现.此实现从 xml 中提取内容并比较列表忽略顺序.
If somebody still want't to use a pure java implementation here it is. This implementation extracts the content from xml and compares the list ignoring order.
public static Document loadXMLFromString(String xml) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
return builder.parse(is);
}
@Test
public void test() throws Exception {
Document doc = loadXMLFromString("<test>
" +
" <elem>b</elem>
" +
" <elem>a</elem>
" +
"</test>");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//test//elem");
NodeList all = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
List<String> values = new ArrayList<>();
if (all != null && all.getLength() > 0) {
for (int i = 0; i < all.getLength(); i++) {
values.add(all.item(i).getTextContent());
}
}
Set<String> expected = new HashSet<>(Arrays.asList("a", "b"));
assertThat("List equality without order",
values, containsInAnyOrder(expected.toArray()));
}
这篇关于比较两个忽略元素顺序的 XML 字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!