Я пытаюсь написать автоматический тест приложения, которое в основном переводит пользовательский формат сообщения в сообщение XML и отправляет его на другой конец. У меня есть хороший набор пар входных / выходных сообщений, поэтому все, что мне нужно сделать, это отправить входные сообщения и прослушать, чтобы сообщение XML вышло на другом конце.
Когда приходит время сравнивать фактический результат с ожидаемым, я сталкиваюсь с некоторыми проблемами. Моей первой мыслью было сравнение строк ожидаемых и фактических сообщений. Это не очень хорошо работает, потому что примеры данных, которые мы имеем, не всегда отформатированы согласованно, и часто для разных пространств имен XML часто используются разные псевдонимы (а иногда пространства имен вообще не используются).
Я знаю, что могу проанализировать обе строки, а затем пройтись по каждому элементу и сравнить их самостоятельно, и это не составит большого труда, но я чувствую, что есть лучший способ или библиотека, которую я мог бы использовать.
Итак, вопрос:
Учитывая две строки Java, которые содержат действительный XML, как бы вы определили, являются ли они семантически эквивалентными? Бонусные баллы, если у вас есть способ определить, в чем различия.
Следующее проверит, равны ли документы, используя стандартные библиотеки JDK.
Нормализуйте (), чтобы убедиться, что нет циклов (технически их не будет)
Приведенный выше код потребует, чтобы пробелы были одинаковыми внутри элементов, потому что он сохраняет и оценивает его. Стандартный синтаксический анализатор XML, который поставляется с Java, не позволяет вам установить функцию для предоставления канонической версии или понять,
xml:space
если это будет проблемой, тогда вам может понадобиться заменяющий синтаксический анализатор XML, такой как xerces, или использовать JDOM.источник
setIgnoringElementContentWhitespace(false)
У Xom есть утилита Canonicalizer, которая превращает ваши DOM в обычную форму, которую вы можете затем упорядочить и сравнить. Таким образом, независимо от пробелов или порядка следования атрибутов, вы можете получать регулярные, предсказуемые сравнения ваших документов.
Это особенно хорошо работает в средах разработки, в которых есть специальные компараторы визуальных строк, например Eclipse. Вы получаете визуальное представление о семантических различиях между документами.
источник
Последняя версия XMLUnit может помочь утверждению, что два XML равны. Также
XMLUnit.setIgnoreWhitespace()
иXMLUnit.setIgnoreAttributeOrder()
может понадобиться рассматриваемый случай.См. Рабочий код простого примера использования модуля XML ниже.
Если вы используете Maven, добавьте это в ваш
pom.xml
:источник
Спасибо, я продлил это, попробуйте это ...
источник
Основываясь на ответе Тома , вот пример использования XMLUnit v2.
Он использует эти зависимости Maven
..и вот тестовый код
Документация, которая обрисовывает в общих чертах это, является https://github.com/xmlunit/xmlunit#comparing-two-documents
источник
Скаффман, кажется, дает хороший ответ.
Другой способ - это, вероятно, отформатировать XML с помощью утилиты командной строки, такой как xmlstarlet ( http://xmlstar.sourceforge.net/ ), а затем отформатировать обе строки и затем использовать любую утилиту diff (библиотеку) для преобразования полученных выходных файлов. Я не знаю, является ли это хорошим решением, когда проблемы с пространствами имен.
источник
AssertJ 1.4+ имеет конкретные утверждения для сравнения содержимого XML:
Вот документация
источник
Я использую Altova DiffDog, который имеет опции для структурного сравнения файлов XML (игнорируя строковые данные).
Это означает, что (если выбрана опция «игнорировать текст»):
и
равны в том смысле, что они имеют структурное равенство. Это удобно, если у вас есть примеры файлов, которые отличаются данными, но не имеют структуры!
источник
Это позволит сравнить полные строковые XML-файлы (переформатировать их в пути). Это облегчает работу с вашей IDE (IntelliJ, Eclipse), потому что вы просто нажимаете и визуально видите разницу в файлах XML.
Я предпочитаю это XmlUnit, потому что клиентский код (тестовый код) чище.
источник
Ниже код работает для меня
источник
Использование JExamXML с Java-приложением
источник
Мне потребовалась та же функциональность, что и в основном вопросе. Поскольку мне не разрешалось использовать какие-либо сторонние библиотеки, я создал собственное решение на основе решения @Archimedes Trajano.
Следующее - мое решение.
Он сравнивает две строки XML и заботится о любых несовпадающих сопоставлениях пространства имен, переводя их в уникальные значения в обеих входных строках.
Может быть точно настроено, например, в случае трансляции пространств имен. Но для моих требований просто делает работу.
источник
Поскольку вы говорите «семантически эквивалентный», я предполагаю, что вы имеете в виду, что вы хотите сделать больше, чем просто буквально проверить, что выходные данные XML (строка) равны, и что вы хотите что-то вроде
<foo> кое-что здесь </ foo> </ code>
и
<foo> кое-что здесь </ foo> </ code>
читать как эквивалент. В конечном счете, будет иметь значение, как вы определяете «семантически эквивалентный» для любого объекта, из которого вы восстанавливаете сообщение. Просто создайте этот объект из сообщений и используйте пользовательский equals (), чтобы определить, что вы ищете.
источник