Я пытаюсь написать автоматический тест приложения, которое в основном переводит пользовательский формат сообщения в сообщение XML и отправляет его на другой конец. У меня есть хороший набор пар сообщений ввода / вывода, поэтому все, что мне нужно сделать, это отправить входные сообщения и прослушать XML-сообщение, которое выйдет на другой конец.
Когда приходит время сравнить фактический результат с ожидаемым, я сталкиваюсь с некоторыми проблемами. Моя первая мысль заключалась в том, чтобы просто сравнить строки ожидаемых и фактических сообщений. Это не работает очень хорошо, потому что данные примеров, которые у нас есть, не всегда отформатированы согласованно, и часто бывают разные псевдонимы, используемые для пространства имен XML (а иногда пространства имен вообще не используются).
Я знаю, что могу проанализировать обе строки, а затем пройтись по каждому элементу и сравнить их самостоятельно, и это будет не так уж сложно, но у меня такое чувство, что есть способ получше или библиотека, которую я мог бы использовать.
Итак, сводится к следующему:
Учитывая две строки Java, каждая из которых содержит допустимый XML, как бы вы определить, являются ли они семантически эквивалентными? Бонусные баллы, если у вас есть способ определить, в чем разница.




Xom имеет служебную программу Canonicalizer, которая превращает ваши модели DOM в обычную форму, которую вы затем можете преобразовывать в строки и сравнивать. Таким образом, независимо от неправильных пробелов или порядка атрибутов, вы можете получать регулярные предсказуемые сравнения ваших документов.
Это особенно хорошо работает в IDE, в которых есть специальные визуальные компараторы String, например Eclipse. Вы получаете наглядное представление о семантических различиях между документами.
Похоже на работу для XMLUnit
Пример:
public class SomeTest extends XMLTestCase {
@Test
public void test() {
String xml1 = ...
String xml2 = ...
XMLUnit.setIgnoreWhitespace(true); // ignore whitespace differences
// can also compare xml Documents, InputSources, Readers, Diffs
assertXMLEqual(xml1, xml2); // assertXMLEquals comes from XMLTestCase
}
}
У меня были проблемы с XMLUNit в прошлом, он был очень дерганым с версиями XML API и не оказался надежным. Однако прошло некоторое время с тех пор, как я отказался от него для XOM, так что, возможно, с тех пор он улучшился.
Для новичков в XMLUnit обратите внимание, что по умолчанию myDiff.similar () будет возвращать ложный, если контрольный и тестовый документы отличаются отступом / новой строкой. Я ожидал такого поведения от myDiff.identical (), а не от myDiff.similar (). Включить XMLUnit.setIgnoreWhitespace (true); в вашем методе setUp, чтобы изменить поведение для всех тестов в вашем тестовом классе, или использовать его в отдельном методе тестирования, чтобы изменить поведение только для этого теста.
@Stew спасибо за ваш комментарий, только начинаю с XMLUnit и я уверен, что столкнулся бы с этой проблемой. +1
Если вы пытаетесь это сделать с XMLUnit 2 на github, версия 2 - это полная переработка, поэтому этот пример предназначен для XMLUnit 1 на SourceForge. Кроме того, на странице sourceforge указано, что «XMLUnit для Java 1.x по-прежнему будет поддерживаться».
В этом примере Junit 3, который использует extends TestCase, действительно олдскульный. Было бы очень полезно использовать пример Junit 4.
метод assertXMLEqual как из XMLAssert.java.
@skaffman, по общему признанию, 10 лет спустя .... но xmlunit очень хорошо работает для меня в тестах JUnit 4.
Скаффман, кажется, дает хороший ответ.
другой способ, вероятно, - отформатировать XML с помощью утилиты командной строки, такой как xmlstarlet (http://xmlstar.sourceforge.net/), а затем отформатировать обе строки, а затем использовать любую утилиту (библиотеку) diff для сравнения полученных выходных файлов. Я не знаю, хорошее ли это решение, когда возникают проблемы с пространствами имен.
Поскольку вы говорите «семантически эквивалентный», я предполагаю, что вы имеете в виду, что хотите сделать больше, чем просто проверить, что выходные данные xml равны (строка), и что вам нужно что-то вроде
<foo> кое-что здесь </foo> </code>
и
<foo> кое-что здесь </foo> </code>
читать как эквивалент. В конечном итоге будет иметь значение, как вы определяете «семантически эквивалент» для любого объекта, из которого вы воссоздаете сообщение. Просто создайте этот объект из сообщений и используйте специальный метод equals (), чтобы определить, что вы ищете.
Не ответ, а вопрос.
Я использую Альтова ДиффДог, у которого есть параметры для структурного сравнения файлов XML (игнорируя строковые данные).
Это означает, что (если установлен флажок «игнорировать текст»):
<foo a = "xxx" b = "xxx">xxx</foo>
и
<foo b = "yyy" a = "yyy">yyy</foo>
равны в том смысле, что имеют структурное равенство. Это удобно, если у вас есть файлы примеров, которые отличаются данными, но не структурой!
Единственный минус в том, что это не бесплатно (99 евро за профессиональную лицензию) с 30-дневной пробной версией.
Нашел только утилиту (altova.com/diffdog/diff-merge-tool.html); приятно иметь библиотеку.
Следующее будет проверять, равны ли документы, используя стандартные библиотеки JDK.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setCoalescing(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc1 = db.parse(new File("file1.xml"));
doc1.normalizeDocument();
Document doc2 = db.parse(new File("file2.xml"));
doc2.normalizeDocument();
Assert.assertTrue(doc1.isEqualNode(doc2));
normalize () нужен для того, чтобы убедиться в отсутствии циклов (технически их не было бы)
Приведенный выше код потребует, чтобы пробелы были одинаковыми внутри элементов, потому что он сохраняет и оценивает его. Стандартный синтаксический анализатор XML, поставляемый с Java, не позволяет вам установить функцию для предоставления канонической версии или понимания xml:space, если это будет проблемой, тогда вам может потребоваться замена синтаксического анализатора XML, например xerces, или использовать JDOM.
Это отлично работает для XML без пространств имен или с «нормализованными» префиксами пространств имен. Я сомневаюсь, что это работает, если один XML - это <ns1: a xmlns: ns1 = "ns" />, а другой - <ns2: a xmlns: ns2 = "ns" />
dbf.setIgnoringElementContentWhitespace (true) не дает результата, я бы ожидал, что <root> name </root> не равно <root> name </name> с этим решением (с двумя пробелами), но XMLUnit дает тот же результат в этом случае (JDK8)
Для меня он не игнорирует разрывы строк, что является проблемой.
setIgnoringElementContentWhitespace(false)
Спасибо, я продлил это, попробуйте это ...
import java.io.ByteArrayInputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
public class XmlDiff
{
private boolean nodeTypeDiff = true;
private boolean nodeValueDiff = true;
public boolean diff( String xml1, String xml2, List<String> diffs ) throws Exception
{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setCoalescing(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc1 = db.parse(new ByteArrayInputStream(xml1.getBytes()));
Document doc2 = db.parse(new ByteArrayInputStream(xml2.getBytes()));
doc1.normalizeDocument();
doc2.normalizeDocument();
return diff( doc1, doc2, diffs );
}
/**
* Diff 2 nodes and put the diffs in the list
*/
public boolean diff( Node node1, Node node2, List<String> diffs ) throws Exception
{
if ( diffNodeExists( node1, node2, diffs ) )
{
return true;
}
if ( nodeTypeDiff )
{
diffNodeType(node1, node2, diffs );
}
if ( nodeValueDiff )
{
diffNodeValue(node1, node2, diffs );
}
System.out.println(node1.getNodeName() + "/" + node2.getNodeName());
diffAttributes( node1, node2, diffs );
diffNodes( node1, node2, diffs );
return diffs.size() > 0;
}
/**
* Diff the nodes
*/
public boolean diffNodes( Node node1, Node node2, List<String> diffs ) throws Exception
{
//Sort by Name
Map<String,Node> children1 = new LinkedHashMap<String,Node>();
for( Node child1 = node1.getFirstChild(); child1 != null; child1 = child1.getNextSibling() )
{
children1.put( child1.getNodeName(), child1 );
}
//Sort by Name
Map<String,Node> children2 = new LinkedHashMap<String,Node>();
for( Node child2 = node2.getFirstChild(); child2!= null; child2 = child2.getNextSibling() )
{
children2.put( child2.getNodeName(), child2 );
}
//Diff all the children1
for( Node child1 : children1.values() )
{
Node child2 = children2.remove( child1.getNodeName() );
diff( child1, child2, diffs );
}
//Diff all the children2 left over
for( Node child2 : children2.values() )
{
Node child1 = children1.get( child2.getNodeName() );
diff( child1, child2, diffs );
}
return diffs.size() > 0;
}
/**
* Diff the nodes
*/
public boolean diffAttributes( Node node1, Node node2, List<String> diffs ) throws Exception
{
//Sort by Name
NamedNodeMap nodeMap1 = node1.getAttributes();
Map<String,Node> attributes1 = new LinkedHashMap<String,Node>();
for( int index = 0; nodeMap1 != null && index < nodeMap1.getLength(); index++ )
{
attributes1.put( nodeMap1.item(index).getNodeName(), nodeMap1.item(index) );
}
//Sort by Name
NamedNodeMap nodeMap2 = node2.getAttributes();
Map<String,Node> attributes2 = new LinkedHashMap<String,Node>();
for( int index = 0; nodeMap2 != null && index < nodeMap2.getLength(); index++ )
{
attributes2.put( nodeMap2.item(index).getNodeName(), nodeMap2.item(index) );
}
//Diff all the attributes1
for( Node attribute1 : attributes1.values() )
{
Node attribute2 = attributes2.remove( attribute1.getNodeName() );
diff( attribute1, attribute2, diffs );
}
//Diff all the attributes2 left over
for( Node attribute2 : attributes2.values() )
{
Node attribute1 = attributes1.get( attribute2.getNodeName() );
diff( attribute1, attribute2, diffs );
}
return diffs.size() > 0;
}
/**
* Check that the nodes exist
*/
public boolean diffNodeExists( Node node1, Node node2, List<String> diffs ) throws Exception
{
if ( node1 == null && node2 == null )
{
diffs.add( getPath(node2) + ":node " + node1 + "! = " + node2 + "\n" );
return true;
}
if ( node1 == null && node2 != null )
{
diffs.add( getPath(node2) + ":node " + node1 + "! = " + node2.getNodeName() );
return true;
}
if ( node1 != null && node2 == null )
{
diffs.add( getPath(node1) + ":node " + node1.getNodeName() + "! = " + node2 );
return true;
}
return false;
}
/**
* Diff the Node Type
*/
public boolean diffNodeType( Node node1, Node node2, List<String> diffs ) throws Exception
{
if ( node1.getNodeType() != node2.getNodeType() )
{
diffs.add( getPath(node1) + ":type " + node1.getNodeType() + "! = " + node2.getNodeType() );
return true;
}
return false;
}
/**
* Diff the Node Value
*/
public boolean diffNodeValue( Node node1, Node node2, List<String> diffs ) throws Exception
{
if ( node1.getNodeValue() == null && node2.getNodeValue() == null )
{
return false;
}
if ( node1.getNodeValue() == null && node2.getNodeValue() != null )
{
diffs.add( getPath(node1) + ":type " + node1 + "! = " + node2.getNodeValue() );
return true;
}
if ( node1.getNodeValue() != null && node2.getNodeValue() == null )
{
diffs.add( getPath(node1) + ":type " + node1.getNodeValue() + "! = " + node2 );
return true;
}
if ( !node1.getNodeValue().equals( node2.getNodeValue() ) )
{
diffs.add( getPath(node1) + ":type " + node1.getNodeValue() + "! = " + node2.getNodeValue() );
return true;
}
return false;
}
/**
* Get the node path
*/
public String getPath( Node node )
{
StringBuilder path = new StringBuilder();
do
{
path.insert(0, node.getNodeName() );
path.insert( 0, "/" );
}
while( ( node = node.getParentNode() ) != null );
return path.toString();
}
}
Довольно поздно, но просто хотел отметить, что в этом фрагменте кода есть ошибка: в diffNodes () на node2 нет ссылки - второй цикл повторно использует node1 неправильно (я отредактировал код, чтобы исправить это). Кроме того, у него есть одно ограничение: из-за того, что дочерние карты связаны с ключами, этот diff не поддерживает случай, когда имена элементов не уникальны, то есть элементы, содержащие повторяющиеся дочерние элементы.
Использование JExamXML с приложением Java
import com.a7soft.examxml.ExamXML;
import com.a7soft.examxml.Options;
.................
// Reads two XML files into two strings
String s1 = readFile("orders1.xml");
String s2 = readFile("orders.xml");
// Loads options saved in a property file
Options.loadOptions("options");
// Compares two Strings representing XML entities
System.out.println( ExamXML.compareXMLString( s1, s2 ) );
Последняя версия XMLUnit может помочь в утверждении равенства двух XML. Также для рассматриваемого случая могут потребоваться XMLUnit.setIgnoreWhitespace() и XMLUnit.setIgnoreAttributeOrder().
См. Рабочий код простого примера использования модуля XML ниже.
import org.custommonkey.xmlunit.DetailedDiff;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Assert;
public class TestXml {
public static void main(String[] args) throws Exception {
String result = "<abc attr=\"value1\" title=\"something\"> </abc>";
// will be ok
assertXMLEquals("<abc attr=\"value1\" title=\"something\"></abc>", result);
}
public static void assertXMLEquals(String expectedXML, String actualXML) throws Exception {
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreAttributeOrder(true);
DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML));
List<?> allDifferences = diff.getAllDifferences();
Assert.assertEquals("Differences found: "+ diff.toString(), 0, allDifferences.size());
}
}
Если вы используете Maven, добавьте это в свой pom.xml:
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<version>1.4</version>
</dependency>
Это идеально подходит для людей, которым нужно сравнивать статическим методом.
Это прекрасный ответ. Спасибо .. Однако мне нужно игнорировать несуществующие узлы. Поскольку я не хочу видеть в выводе результата такой вывод: Ожидаемое присутствие дочернего узла "null", но было ...... Как я могу это сделать? С уважением. @acdcjunior
XMLUnit.setIgnoreAttributeOrder (истина); не работает. Если некоторые узлы имеют другой порядок, сравнение не удастся.
[ОБНОВЛЕНИЕ] это решение работает: stackoverflow.com/questions/33695041/…
Вы ведь понимаете, что «IgnoreAttributeOrder» означает игнорировать порядок атрибутов и не игнорировать порядок узлов, верно?
@acdcjunior Если узлы находятся в разных местах ... это сработает?
@AbhijitBashetti Видимо только когда еще добавляешь .withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.byName)).
DiffBuilder.compare (bufferedReaderExistingFile) .withTest (bufferedReaderNewFile) .ignoreComments () .ignoreWhitespace () .withNodeMatcher (новый DefaultNodeMatcher (ElementSelectors.byName)) .checkForSimilar () .build ();
@acdcjunior: у меня есть код выше, но он говорит, что файлы разные
@AbhijitBashetti хм ... это плохо ... извини, у меня больше ничего нет ?
Это позволит сравнить полные строковые XML-файлы (по ходу переформатируя их). Это упрощает работу с вашей IDE (IntelliJ, Eclipse), потому что вы просто нажимаете и визуально видите разницу в файлах XML.
import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.IOException;
import java.io.StringReader;
import static org.apache.xml.security.Init.init;
import static org.junit.Assert.assertEquals;
public class XmlUtils {
static {
init();
}
public static String toCanonicalXml(String xml) throws InvalidCanonicalizerException, ParserConfigurationException, SAXException, CanonicalizationException, IOException {
Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
byte canonXmlBytes[] = canon.canonicalize(xml.getBytes());
return new String(canonXmlBytes);
}
public static String prettyFormat(String input) throws TransformerException, ParserConfigurationException, IOException, SAXException, InstantiationException, IllegalAccessException, ClassNotFoundException {
InputSource src = new InputSource(new StringReader(input));
Element document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
Boolean keepDeclaration = input.startsWith("<?xml");
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
LSSerializer writer = impl.createLSSerializer();
writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
writer.getDomConfig().setParameter("xml-declaration", keepDeclaration);
return writer.writeToString(document);
}
public static void assertXMLEqual(String expected, String actual) throws ParserConfigurationException, IOException, SAXException, CanonicalizationException, InvalidCanonicalizerException, TransformerException, IllegalAccessException, ClassNotFoundException, InstantiationException {
String canonicalExpected = prettyFormat(toCanonicalXml(expected));
String canonicalActual = prettyFormat(toCanonicalXml(actual));
assertEquals(canonicalExpected, canonicalActual);
}
}
Я предпочитаю это XmlUnit, потому что клиентский код (тестовый код) чище.
Это отлично работает в двух тестах, которые я сделал сейчас, с тем же XML и с другим XML. С IntelliJ diff легко заметить различия в сравниваемых XML.
Кстати, эта зависимость вам понадобится, если вы используете Maven: <dependency> <groupId> org.apache.santuario </groupId> <artifactId> xmlsec </artifactId> <version> 2.0.6 </version> </ зависимость>
Основываясь на ответе Том, вот пример использования XMLUnit v2.
Он использует эти зависимости maven
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-matchers</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
..и вот тестовый код
import static org.junit.Assert.assertThat;
import static org.xmlunit.matchers.CompareMatcher.isIdenticalTo;
import org.xmlunit.builder.Input;
import org.xmlunit.input.WhitespaceStrippedSource;
public class SomeTest extends XMLTestCase {
@Test
public void test() {
String result = "<root></root>";
String expected = "<root> </root>";
// ignore whitespace differences
// https://github.com/xmlunit/user-guide/wiki/Providing-Input-to-XMLUnit#whitespacestrippedsource
assertThat(result, isIdenticalTo(new WhitespaceStrippedSource(Input.from(expected).build())));
assertThat(result, isIdenticalTo(Input.from(expected).build())); // will fail due to whitespace differences
}
}
Документация, описывающая это, - https://github.com/xmlunit/xmlunit#comparing-two-documents
AssertJ 1.4+ имеет определенные утверждения для сравнения содержимого XML:
String expectedXml = "<foo />";
String actualXml = "<bar />";
assertThat(actualXml).isXmlEqualTo(expectedXml);
Вот Документация
Однако тривиальная разница в префиксе пространства имен между двумя документами приводит к сбою AssertJ. AssertJ - отличный инструмент, но на самом деле он предназначен для XMLUnit.
Мне требовались те же функции, что и в основном вопросе. Поскольку мне не разрешалось использовать какие-либо сторонние библиотеки, я создал собственное решение на основе решения @Archimedes Trajano.
Вот мое решение.
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Assert;
import org.w3c.dom.Document;
/**
* Asserts for asserting XML strings.
*/
public final class AssertXml {
private AssertXml() {
}
private static Pattern NAMESPACE_PATTERN = Pattern.compile("xmlns:(ns\d+)=\"(.*?)\"");
/**
* Asserts that two XML are of identical content (namespace aliases are ignored).
*
* @param expectedXml expected XML
* @param actualXml actual XML
* @throws Exception thrown if XML parsing fails
*/
public static void assertEqualXmls(String expectedXml, String actualXml) throws Exception {
// Find all namespace mappings
Map<String, String> fullnamespace2newAlias = new HashMap<String, String>();
generateNewAliasesForNamespacesFromXml(expectedXml, fullnamespace2newAlias);
generateNewAliasesForNamespacesFromXml(actualXml, fullnamespace2newAlias);
for (Entry<String, String> entry : fullnamespace2newAlias.entrySet()) {
String newAlias = entry.getValue();
String namespace = entry.getKey();
Pattern nsReplacePattern = Pattern.compile("xmlns:(ns\d+)=\"" + namespace + "\"");
expectedXml = transletaNamespaceAliasesToNewAlias(expectedXml, newAlias, nsReplacePattern);
actualXml = transletaNamespaceAliasesToNewAlias(actualXml, newAlias, nsReplacePattern);
}
// nomralize namespaces accoring to given mapping
DocumentBuilder db = initDocumentParserFactory();
Document expectedDocuemnt = db.parse(new ByteArrayInputStream(expectedXml.getBytes(Charset.forName("UTF-8"))));
expectedDocuemnt.normalizeDocument();
Document actualDocument = db.parse(new ByteArrayInputStream(actualXml.getBytes(Charset.forName("UTF-8"))));
actualDocument.normalizeDocument();
if (!expectedDocuemnt.isEqualNode(actualDocument)) {
Assert.assertEquals(expectedXml, actualXml); //just to better visualize the diffeences i.e. in eclipse
}
}
private static DocumentBuilder initDocumentParserFactory() throws ParserConfigurationException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);
dbf.setCoalescing(true);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setIgnoringComments(true);
DocumentBuilder db = dbf.newDocumentBuilder();
return db;
}
private static String transletaNamespaceAliasesToNewAlias(String xml, String newAlias, Pattern namespacePattern) {
Matcher nsMatcherExp = namespacePattern.matcher(xml);
if (nsMatcherExp.find()) {
xml = xml.replaceAll(nsMatcherExp.group(1) + "[:]", newAlias + ":");
xml = xml.replaceAll(nsMatcherExp.group(1) + " = ", newAlias + " = ");
}
return xml;
}
private static void generateNewAliasesForNamespacesFromXml(String xml, Map<String, String> fullnamespace2newAlias) {
Matcher nsMatcher = NAMESPACE_PATTERN.matcher(xml);
while (nsMatcher.find()) {
if (!fullnamespace2newAlias.containsKey(nsMatcher.group(2))) {
fullnamespace2newAlias.put(nsMatcher.group(2), "nsTr" + (fullnamespace2newAlias.size() + 1));
}
}
}
}
Он сравнивает две строки XML и заботится о любых несоответствующих сопоставлениях пространств имен, переводя их в уникальные значения в обеих входных строках.
Возможна точная настройка, например, в случае перевода пространств имен. Но для моих требований просто выполняет свою работу.
Ниже код работает для меня
String xml1 = ...
String xml2 = ...
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setIgnoreAttributeOrder(true);
XMLAssert.assertXMLEqual(actualxml, xmlInDb);
Любой контекст? Ссылка на библиотеку?
Я знал, что должно быть что-то подобное. Не могу поверить, что Google не нашел его для меня. Спасибо.