Я ищу API, который сравнивает два XML-данных. Я пробовал 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) нельзя заказатьИщем API, который возвращает true, например:
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();




Вы можете попробовать, как показано ниже
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();
}
}
}
Я копирую здесь метод, который мы используем в моем проекте.
Не могли бы вы попробовать и дайте мне знать, если вы столкнулись с какой-либо проблемой. Я могу попробовать сам еще раз.
Спасибо
Самая большая проблема, вероятно, заключается в том, «какие элементы соответствуют url?». Я могу только догадываться и предполагать, что url с одинаковым текстом внутри дочернего элемента loc являются совпадающими элементами - и это то, что вам нужно сообщить XMLUnit.
Ваш пример очень распространен, но все же его нельзя угадать (кроме перебора всех возможных перестановок и выбора варианта с наименьшими различиями). Это рабочий пример https://github.com/xmunit/user-guide/wiki/Выбор узлов, вам нужно всего лишь заменить tr на uri и th на loc.
Чтобы сделать вещи конкретными. При сравнении элементов url вы хотите, чтобы XMLUnit просматривал соответствующие дочерние элементы loc и сравнивал их вложенный текст. Во всех остальных случаях вы можете выбирать среди родственных элементов по их имени (есть только один urlset, и каждая пара loc и lastmod однозначно определяется именами их тегов).
The переводится как условное ElementSelector
ElementSelectors.conditionalBuilder()
.whenElementIsNamed("url").thenUse(ElementSelectors
.byXPath("./loc", ElementSelectors.byNameAndText))
.elseUse(ElementSelectors.byName)
.build();
При этом вы сможете получить «похожий» результат, где единственными обнаруженными различиями являются различия в дочернем порядке.