Программный XML Diff/Merge в С#
В данный момент я управляю частью программного обеспечения, имеющего несколько файлов конфигурации XML. Когда выпущена новая версия программного обеспечения, иногда файлы базовых конфигураций меняются, в настоящее время мы запускаем программный вызов KDiff при запуске. Если он обнаруживает изменение, он предлагает пользователю выбрать изменения.
Проблема с этим подходом заключается в том, что KDiff - это программа сравнения строк и не знает пути XML (например, узлы и т.д.).
В идеале я хотел бы программно работать с библиотекой на С# (так как мы являемся магазином MS), который может Diff два файла XML: исходный XML и текущий рабочий XML.
И затем объедините их вместе с помощью нескольких простых правил:
- Если текущий рабочий XML имеет node, который отсутствует в исходном XML файле, удалите его.
- Если исходный XML имеет node, который не поддерживает текущий рабочий XML, добавьте его.
- Если оба имеют одинаковый node и значения различаются, используйте значение Source XML, если только значение исходного XML не установлено на "UseExistingValue".
Например, здесь "Источник" XML:
<Configuration>
<Items>
<Item Id="1" Position="true">
<Location X="UseExistingValue" Y="UseExistingValue" Z="UseExistingValue" />
<Something/>
<SomethingElse/>
</Item>
</Items>
</Configuration>
И здесь "Текущий рабочий" XML:
<Configuration>
<Items>
<Item Id="1" Position="false">
<Location X="123" Y="234" Z="345" />
<Another/>
<Something/>
</Item>
</Items>
</Configuration>
И объединенная версия будет выглядеть так:
<Configuration>
<Items>
<Item Id="1" Position="true">
<Location X="123" Y="234" Z="345" />
<Something/>
<SomethingElse/>
</Item>
</Items>
</Configuration>
Я просмотрел MS Diff и Patch Tool, и он определенно объединяет файлы вместе, но не позволяет программным правила, которые я хочу определить.
XMLUnit для Java-разработчиков кажется многообещающим, но версия .NET выглядит слаборазвитой, что является неудачным.
У кого-нибудь есть предложения для скриптовых инструментов XML Diff/Merge и/или .NET-библиотек (платных или бесплатных)?
Спасибо.
Ответы
Ответ 1
После нескольких дней беспорядков я нашел решение, которое, как мне кажется, работает для меня. Возможно, это может сработать и для других людей.
Средство MS Diff и Patch было жизнеспособным вариантом. Когда вы Diff первый файл со вторым файлом, он создает XML "DiffGram", в котором перечисляются изменения, которые он обнаружил между двумя файлами XML.
Чтобы позаботиться обо всех трех правилах, перечисленных выше, я выполнил два файла в одном направлении, затем открыл файл DiffGram с использованием Linq-to-XML и удалил все строки "Добавить" и "Удалить".
XNamespace xd = "http://schemas.microsoft.com/xmltools/2002/xmldiff";
var doc = XDocument.Load(_diffGramFile);
doc.Root.DescendantsAndSelf(xd + "add").Remove();
doc.Root.DescendantsAndSelf(xd + "remove").Remove();
Затем я закрепил (объединил) этот отредактированный diffgram против первого файла и создал частично объединенный временный файл. Это позаботится о правилах 1 и 2.
Далее, я Diff'd частично объединенный файл против первого используемого файла. Затем открыли новый DiffGram и удалили все ссылки на ссылку "UseExistingValue".
var newdoc = XDocument.Load(_diffGramFile);
newdoc.Root.DescendantsAndSelf(xd + "change")
.Where(x => x.Value == "UseExistingValue").Remove();
И объединил этот отредактированный DiffGram с частично объединенным файлом, который заботится о правиле 3. Сохранение этого в XML затем приводит к окончательному объединению XML в соответствии с правилами, определенными выше.
Надеюсь, это поможет другим людям.
СОВЕТ. После установки библиотеки XmlDiffPatch библиотеку XmlDiffPatch можно найти в C:\Windows\assembly\GAC\XmlDiffPatch\1.0.8.28__b03f5f7f11d50a3a\XmlDiffPatch.dll