Як я можу розрізняти два XML-файли?


75

Як в Linux можна створити різницю між двома файлами XML?

В ідеалі я хотів би мати можливість налаштувати його на деякі речі суворо, або послабити деякі речі, наприклад пробіл або порядок атрибутів.

Мене часто хвилює те, що файли функціонально однакові, але відрізняються самі по собі, буде прикро використовувати, особливо якщо у файлу XML не так багато рядків.

Наприклад, мені справді все в порядку:

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

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

Відповіді:


86

Одним із підходів було б спочатку перетворити обидва файли XML у Canonical 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 постачається з ОС X
ClintM

10
Якщо це не було очевидно, c14n - це абревіатура для канонізації .
Брандін

3
Краще виконати додатковий крок перед різним форматуванням обох XML (xmllint --format). Тому що я помітив, що без цього кроку розбіжність показує більше відмінностей, ніж потрібно.
ka3ak

23

Відповідь Юкки не працювала для мене, але вона вказувала на Canonical 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 Гб (оперативна пам’ять + SWAP) при порівнянні двох файлів ~ 20 тис. рядків кожен
Grzegorz

зауважте, що проект здається мертвим, останнє оновлення у 2013 році
Матеуш Конічний

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

У прикладі ОП це не дало б нічого та поверне статус виходу 0(без структурних чи текстових відмінностей).

У випадках, коли 1.xmlі 2.xmlвідрізняються структурно, це імітує уніфікований вихід GNU diff і повертає вихідний статус 1. Існують різні варіанти керування висновком, такі як -aвиведення всього контексту, -nвиведення без контексту та -qзагальне придушення виводу (при цьому все ще повертають статус виходу).


0

Я використовую програму Beyond Compare для порівняння всіх типів текстових файлів. Вони виробляють версії для Windows та Linux.


1
Звичайне порівняння тексту скаже, що два рядки різняться, тоді як ОП хоче, щоб вони повідомлялися як однакові.
ChrisF

4
тобто Canonically порівняти XML.
Кріс В. Реа

1
Більше Порівняння дійсно гарно для цього. Здається, вони просто не знають про елементи XML і роблять здебільшого лише порівняння тексту.
Роб К

Більше порівняння має плагін XML, але я ніколи не зміг його встановити належним чином, так що ... Так ... я зайшов на цю сторінку і став розумнішим ...
Ерк

-1

Наш Smart Smart Differencer порівнює документи на основі структури на відміну від фактичної верстки.

Є XML Smart Differencer. Для XML це означає узгодження порядку тегів та вмісту. Слід зазначити, що текстовий рядок у конкретному вказаному вами фрагменті відрізнявся. Наразі воно не розуміє поняття XML атрибутів тегів, що вказує на те, чи нормалізується пробіл проти значущого.


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

1
Ага. Дякуємо за нагадування. Це відповідь часів, перш ніж була чітка політика щодо цього питання. Я переглядаю відповідь, щоб сигналізувати про взаємозв'язок у відповіді на політику SO.
Іра Бакстер

Я перевірю сторінку завантаження; не всі наші живі продукти входять до цього списку. Так, такі існують.
Іра Бакстер

Я перевірив сторінку завантаження. Так, розумної різниці XML немає. У мене будуть задні хлопці працювати над тим, щоб це виправити; має бути там не більше 1-2 тижнів (вони мають відставання, чи не всі ми?). Тим часом, якщо ви хочете спробувати, надішліть електронний лист (див. біо).
Іра Бакстер

1
На пов’язаній сторінці немає в ній слова "XML".
Матеуш Коньєчний

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.