我正在寻找比较两个XML数据的API。我已经尝试过XMLUnit 2,但是找不到与我的示例兼容的方法。你能给我一个适合我需要的例子吗?
我的第一个XML数据xml1
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<urlset xmlns="http://www.sitemap.org/schemas/sitemap/0.9">
<url>
<loc>a1/</loc>
<lastmod>a2</lastmod>
</url>
<url>
<loc>b1</loc>
<lastmod>b2</lastmod>
</url>
<url>
<loc>c1</loc>
<lastmod>c2</lastmod>
</url>
</urlset>
我的第二个XML数据xml2
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<urlset xmlns="http://www.sitemap.org/schemas/sitemap/0.9">
<url><lastmod>b2</lastmod><loc>b1</loc></url>
<url>
<lastmod>c2</lastmod>
<loc>c1</loc>
</url>
<url>
<loc>a1/</loc>
<lastmod>a2</lastmod>
</url>
</urlset>
注意:
urlset
的子节点(url
)可能未排序url
的元素(loc
和lastmod
)不能排序寻找一个返回true
的API,例如:
XMLUtils.isSimilar(xml1, xml2);
我对XMLUnit 2的尝试失败(尝试了多个“ NodeMatcher”):
// Attempt with XmlAssert.assertThat:
XmlAssert.assertThat(xml1)
.and(xml2)
.ignoreChildNodesOrder()
.ignoreWhitespace()
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
.areSimilar();
// Attempt with Diff
Diff myDiff = DiffBuilder.compare(xml1)
.withTest(xml2)
.ignoreWhitespace()
.checkForSimilar()
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byNameAndText))
.build();
myDiff.getDifferences();
答案 0 :(得分:1)
您可以尝试以下操作
public class XMLUtils {
private static DocumentBuilderFactory documentBuilderFactory;
private static DocumentBuilder documentBuilder;
private static TransformerFactory transformerFactory;
private static Transformer transformer;
private static Document emptyDoc;
public XMLUtils() {
}
public XMLCompareResult compare(File expectedFile, File actualFile, boolean ignoreWhiteSpace) throws FileNotFoundException, SAXException, IOException {
FileInputStream expInpStream = new FileInputStream(expectedFile);
FileInputStream actualInpStream = new FileInputStream(actualFile);
Diff myDiff = null;
if (ignoreWhiteSpace) {
myDiff = DiffBuilder.compare(expInpStream).withTest(actualInpStream).checkForSimilar().ignoreWhitespace().withNodeMatcher(new DefaultNodeMatcher(new ElementSelector[]{ElementSelectors.byNameAndAllAttributes})).build();
} else {
myDiff = DiffBuilder.compare(expInpStream).withTest(actualInpStream).checkForSimilar().withNodeMatcher(new DefaultNodeMatcher(new ElementSelector[]{ElementSelectors.byNameAndAllAttributes})).build();
}
XMLResultUtil xmlr = new XMLResultUtil();
XMLCompareResult xs = xmlr.prepareXMLCompareResult(myDiff.getDifferences());
return xs;
}
static {
try {
documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilder = documentBuilderFactory.newDocumentBuilder();
transformerFactory = TransformerFactory.newInstance();
transformer = transformerFactory.newTransformer();
emptyDoc = documentBuilder.newDocument();
} catch (ParserConfigurationException var1) {
var1.printStackTrace();
} catch (TransformerConfigurationException var2) {
var2.printStackTrace();
}
}
}
我在这里复制我们在项目中使用的方法。
您可以尝试一下,如果您遇到任何问题,请告诉我。我可以自己再试一次。
谢谢
答案 1 :(得分:0)
最大的问题可能是“匹配的url
元素是什么?”。我只能猜测并假设url
子元素中具有相同文本的loc
是匹配元素-这就是您需要告诉XMLUnit的地方。
您的示例非常普遍,但仍然无法猜到(除了强制使用所有可能的排列并选择差异最小的排列之外)。这是https://github.com/xmlunit/user-guide/wiki/SelectingNodes的运行示例,您只需将tr
替换为uri
,将th
替换为loc
。
使事情具体化。比较url
元素时,您希望XMLUnit查看相应的loc
子元素并比较它们的嵌套文本。在所有其他情况下,您很乐意按兄弟元素的名称进行选择(只有一个urlset
,每对loc
和lastmod
兄弟姐妹均由其标签名称唯一决定)。
转换为条件ElementSelector
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("url").thenUse(ElementSelectors
.byXPath("./loc", ElementSelectors.byNameAndText))
.elseUse(ElementSelectors.byName)
.build();
这样,您应该能够得出“相似”结果,其中发现的唯一区别是子顺序差异。