Как сравнить XML-файлы

у меня есть два XML-файла (XSD), которые генерируются каким-то инструментом.
Инструмент не сохраняет порядок элементов, поэтому, хотя содержимое равно, сравнение его как текст приведет к тому, что файлы будут отличаться.
Есть ли какой-то инструмент, который может сортировать элементы перед сравнением и позволит сравнивать текст документов? Конечно, сортировка должна выполняться рекурсивно.

сведения пример:
Файл:

<xml>
  <A/>
  <B/>
</xml>
B:
<xml>
  <B/>
  <A/>
</xml>

5 ответов


У меня была аналогичная проблема, и я в конце концов нашел:http://superuser.com/questions/79920/how-can-i-diff-two-xml-files

этот пост предлагает сделать каноническую сортировку xml, а затем сделать diff. Следующее должно работать для вас, если вы находитесь на linux, mac или если у вас установлена windows с чем-то вроде cygwin:

$ xmllint --c14n FileA.xml > 1.xml
$ xmllint --c14n FileB.xml > 2.xml
$ diff 1.xml 2.xml

посмотреть использование XSLT для регрессионного тестирования которые описывают решение с использованием xslt


вы можете использовать модуль perl DifferenceMarkup http://metacpan.org/pod/XML::DifferenceMarkup или xmldiff pecl.php.net/xmldiff расширение в PHP. Оба будут создавать удобочитаемый XML-документ diff.


для чего это стоит, я создал инструмент java (или kotlin на самом деле) для эффективной и настраиваемой канонизации xml-файлов.

Он всегда будет:

  • сортировка узлов и атрибутов по имени.
  • удалить пространства имен (да - это может - гипотетически - быть проблемой).
  • Prettyprint результат.

кроме того, вы можете сказать ему:

  • удалить данный список имен узлов-возможно, вы не хотите знать, что значение фрагмента метаданных-скажем <RequestReceivedTimestamp> изменилось.
  • Сортировать данный список коллекций в контексте родителя-может быть, вам все равно, что порядок <Contact> записи <ListOfFavourites> изменилось.

он использует XSLT и делает все вышеперечисленное эффективно, используя цепочку.

ограничения

он поддерживает сортировку вложенных списков-сортировка внутренних списков перед внешним. Но он не может надежно сортировать произвольные уровни рекурсивно вложенных списков.

Если у вас есть такие потребности, вы можете - после использования этого инструмента - сравнить отсортированные массивы байтов результатов. они будут равны, если останутся только проблемы сортировки списка.

где взять

вы можете получить его здесь: XMLNormalize


образцы XML принципиально отличаются. Несмотря на то, что содержимое и иерархия могут быть идентичными, отношения между сверстниками различны. Когда XML анализируется, он анализируется в структуру, называемую DOM, где отношения между единицами очень важны. Если вы хотите дисконтировать природу отношений между одноранговыми сущностями, вам, вероятно, понадобится пользовательское программное обеспечение. Я рекомендую найти простой инструмент diff с открытым исходным кодом XML и добавить дополнительные требования что тебе нужно. Я написал один в http://prettydiff.com/ но я предлагаю вам посмотреть вокруг, чтобы увидеть, что доступно, прежде чем принимать решение, потому что редактирование чужих алгоритмов может потребовать немного тяжелой работы.