Требуется написать скрипт (на внутрикорпоративном скриптовом языке) для сравнения 2 файлов данных в формате XML и вывода списка различий. Есть API для работы с XML, где есть функции GetRootElement, GetFirstChild, GetNextSibling, GetFirstChildByName, GetNextSiblingByName, GetParent, GetElementTag, GetAttributesCount, GetAttributeByName, GetAttributeByIndex и т.д.
Проблема в следующем. Файлы следует считать одинаковыми, если они отличаются только порядком атрибутов внутри тегов или порядком элементов на одном уровне иерархии.
Вопрос: как лучше сравнивать?
Я сделал следующее.
Для сравнения атрибутов в паре элементов:
- перебрать все атрибуты в 1-м теге, для каждого искать совпадающие во 2-м теге;
- перебрать все атрибуты во 2-м теге, проверить, что каждый есть в 1-м.
Для проверки равенства пары элементов из 2 файлов:
- сравнить тег;
- сравнить атрибуты;
- составить 2 списка детей;
- сравнить число детей;
- рекурсивно сравнивать каждого из детей из 1-го файла с каждым из детей из 2-го файла, отмечая в списках совпадающих; исключать из дальнейшего сравнения тех, для кого нашлась пара.
Для сравнения файлов:
- взять корневые элементы и рекурсивно сравнить.
Как-то оптимизировать можно?
Ответ: Сканировать файл (обход дерева в глубину или ширину), собрать все возможные пути (xpath) в список, сортировать, сравнить. При этом атрибуты каждого узла также сортируются и добавляются в соответствующее место пути. Код сократился почти втрое.