Как я могу различить два файла XML?


75

В Linux, как я могу создать разницу между двумя файлами XML?

В идеале я хотел бы иметь возможность настроить его на некоторые строгие вещи или ослабить некоторые вещи, такие как пробелы или порядок атрибутов.

Я буду часто беспокоиться о том, что файлы функционально одинаковы, но различие само по себе будет раздражать, особенно если файл XML не имеет много разрывов строк.

Например, следующее должно быть хорошо для меня:

<tag att1="one" att2="two">
  content
</tag>

<tag att2="two" att1="one">
  content
</tag>

Ответы:


86

Один из подходов будут первым включить оба XML - файлы в канонический XML , и сравнить полученные результаты с использованием diff. Например, xmllint может использоваться для канонизации XML.

$ xmllint --c14n one.xml > 1.xml
$ xmllint --c14n two.xml > 2.xml
$ diff 1.xml 2.xml

Или как однострочник.

$ diff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)

1
Никогда не знал о ключе --c14n в xmllint. Это удобно
Qedi

18
Вы также можете сделать это в одну строкуvimdiff <(xmllint --c14n one.xml) <(xmllint --c14n two.xml)
Натан Вильяэскуса

и xmllint поставляются с OS X
ClintM

10
В случае, если это не было очевидно, c14n является аббревиатурой для канонизации .
Брандин

3
Лучше выполнить дополнительный шаг перед diff-форматированием обоих XML (xmllint --format). Потому что я заметил, что без этого шага diff показывает больше различий, чем необходимо.
ka3ak

23

Ответ Юкки у меня не сработал, но он указывал на канонический XML. Ни --c14n, ни --c14n11 не отсортировали атрибуты, но я обнаружил, что ключ --exc-c14n действительно отсортировал атрибуты. --exc-c14n не указан на странице руководства, но описан в командной строке как «эксклюзивный канонический формат W3C».

$ xmllint --exc-c14n one.xml > 1.xml
$ xmllint --exc-c14n two.xml > 2.xml
$ diff 1.xml 2.xml

$ xmllint | grep c14
    --c14n : save in W3C canonical format v1.0 (with comments)
    --c14n11 : save in W3C canonical format v1.1 (with comments)
    --exc-c14n : save in W3C exclusive canonical format (with comments)

$ rpm -qf /usr/bin/xmllint
libxml2-2.7.6-14.el6.x86_64
libxml2-2.7.6-14.el6.i686

$ cat /etc/system-release
CentOS release 6.5 (Final)

Предупреждение --exc-c14n удаляет заголовок xml, тогда как --c14n добавляет заголовок xml, если его там нет.


18

Пытался использовать ответ @Jukka Matilainen, но у него были проблемы с пробелами (один из файлов был огромным в одну строку). Использование --formatпомогает пропустить различия между пробелами.

xmllint --format one.xml > 1.xml  
xmllint --format two.xml > 2.xml  
diff 1.xml 2.xml  

Примечание: используйте vimdiffкоманду для параллельного сравнения xmls.


В моем случае two.xmlбыл сгенерирован из one.xmlскрипта. Поэтому мне просто нужно было проверить, что было добавлено / удалено скриптом.
ГуруМ

1
Это был вариант, который мне был нужен. Предположительно, наиболее каноническая версия может быть получена путем сочетания --formatс --exc-c14n; вероятно, будет еще медленнее обрабатывать :(
ᴠɪɴᴄᴇɴᴛ

Прошло довольно много времени с тех пор, как я написал ответ, но я слабо помню, как использовал флаг --exc-c14n. Однако, разметка вывода с / без флага не показала различий, поэтому просто перестала его использовать Удаление ненужных / неиспользуемых флагов может ускорить процесс.
ГуруМ

5
--exc-c14nОпция определяет сортировку атрибутов. В ваших конкретных файлах атрибуты, вероятно, уже отсортированы, но общий совет будет использовать комбинацию --format --exc-c14n.
ᴠɪɴᴄᴇɴᴛ

6

Diffxml обеспечивает правильную базовую функциональность, хотя, похоже, не предлагает много вариантов конфигурации.

Изменить: Project Diffxml был перенесен на GitHub с 2013 года.


Это еще не совсем там, но, по крайней мере, выглядит многообещающе.
Qedi

бесполезно для больших файлов, однако, умер после употребления 40 ГБ (RAM + SWAP) при сравнении двух файлов ~ 20 тыс. строк каждый
Grzegorz

обратите внимание, что проект, кажется, мертв, с последним обновлением в 2013 году
Mateusz Konieczny

4

Если вы также хотите игнорировать порядок дочерних элементов, я написал для этого простой инструмент на языке python xmldiffs:

Сравните два XML-файла, игнорируя элементы и порядок атрибутов.

Использование: xmldiffs [OPTION] FILE1 FILE2

Любые дополнительные параметры передаются diffкоманде.

Получить его на https://github.com/joh/xmldiffs


1

Мой скрипт Python xdiff.py для сравнения XML-файлов игнорирует различия в пробелах или порядке атрибутов (в отличие от порядка элементов).

Чтобы сравнить два файла 1.xmlи 2.xml, вы должны запустить скрипт следующим образом:

xdiff.py 1.xml 2.xml

В примере с OP он ничего не выводил бы и возвращал статус выхода 0(без структурных или текстовых различий).

В тех случаях, когда 1.xmlи 2.xmlструктурно отличаются, он имитирует унифицированный вывод GNU diff и возвращает статус выхода 1. Существуют различные варианты управления выводом, например, -aдля вывода всего контекста, -nдля вывода без контекста и -qдля подавления вывода в целом (при этом все еще возвращая состояние выхода).


0

Я использую Beyond Compare для сравнения всех типов текстовых файлов. Они производят версии для Windows и Linux.


1
Сравнения в простом тексте сказали бы, что две линии различаются, тогда как ФП хочет, чтобы о них сообщалось как об одинаковых
ChrisF

4
т.е. канонически сравнивать XML.
Крис В. Ри

1
Beyond Compare действительно отстой для этого. Кажется, он просто не знает об элементах XML и делает в основном только сравнение текста.
Роб К

В Beyond Compare есть плагин XML, но я так и не смог правильно его установить, так что ... Неее ... Я зашел на эту страницу и стал мудрее ...
Эрк

-1

Наш SD Smart Differencer сравнивает документы на основе структуры, а не фактического макета.

Есть интеллектуальная разница XML. Для XML это означает соответствие порядка тегов и содержимого. Следует отметить, что текстовая строка в указанном вами фрагменте была другой. В настоящее время он не понимает XML-понятие атрибутов тега, указывающее, является ли пробел нормализованным или значимым.


1
В своем профиле SO вы предоставляете полную информацию о своем работодателе; Я бы также предпочел короткий отказ от ответственности в вашем ответе :) Кстати, я пытался загрузить пробную копию, но форма запроса «умная» (через JS) достаточно, чтобы отключить комбинацию XML с Smart Differencer (также последний в сочетании с Python, хотя возможно в соответствии со страницей продукта SD)?
ᴠɪɴᴄᴇɴᴛ

1
Ах. Спасибо за напоминание. Это ответ того времени, когда до этого не было четкой политики SO. Я пересматриваю ответ, чтобы обозначить отношения в ответе, соответствующем политике SO.
Ира Бакстер

Я проверю страницу загрузки; не все наши живые продукты попадают в этот список. Да, они существуют.
Ира Бакстер

Я проверил страницу загрузки. Да, смарт-разницы в XML нет. Я сделаю так, чтобы парни из подсобки работали над тем, чтобы это исправить; должно быть там максимум через 1-2 недели (у них отставание, не все ли?) А пока, если вы хотите попробовать, отправьте электронное письмо (см. биографию).
Ира Бакстер

1
На связанной странице нет слова "XML".
Матеуш Конечны

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.