Сравнение XmlDocument для равенства (контент-мудрый)

Если я хочу сравнить содержимое XMlDocument, это просто так?

XmlDocument doc1 = GetDoc1();
XmlDocument doc2 = GetDoc2();

if(doc1 == doc2)
{

}

Я не проверяю, являются ли они одинаковой ссылкой на объект, но если СОДЕРЖАНИЕ xml одинаково.

Ответ 1

Нет. XmlDocument не переопределяет поведение метода Equals(), поэтому на самом деле это просто выполняет ссылочное равенство, которое не будет выполнено в вашем примере, если только документы не являются одним и тем же экземпляром объекта.

Если вы хотите сравнить содержимое (атрибуты, элементы, коммиты, PI и т.д.) документа, вам придется реализовать эту логику самостоятельно. Будьте предупреждены: это не тривиально.

В зависимости от вашего точного сценария вы можете удалить все несущественные пробелы из документа (что само по себе может быть сложным), и они сравнивают полученный XML-текст. Это не идеально - он не подходит для документов, которые семантически идентичны, но отличаются тем, что используются и объявляются пространства имен, а также некоторые escape-последовательности, порядок элементов и т.д. Как я уже говорил, сравнение XML не является тривиальным.

Вам также необходимо четко определить, что означает, что два документа XML являются "идентичными". Важно ли упорядочение элементов или атрибутов? Имеет ли смысл (в текстовых узлах) вопрос? Следует ли игнорировать лишние разделы CDATA? Удостоверяются ли инструкции обработки? Что относительно полностью квалифицированных или частично квалифицированных пространств имен?

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

Уже существуют инструменты, которые выполняют различие XML, например Microsoft XML Diff/Patch,, вы можете чтобы выявить различия между двумя документами. Насколько мне известно, инструмент не распространяется в исходной форме... поэтому для его использования во встроенном приложении вам потребуется script процесс (если вы планируете его использовать, сначала убедитесь, что условия лицензирования позволяют использовать его и перераспределение).

EDIT: Отправляем @Max Toro answer, если вы используете .NET 3.5 SP1, поскольку, по-видимому, в XLinq есть опция, которая может оказаться полезным. Приятно знать, что он существует.

Ответ 3

Простым способом может быть сравнение OuterXml.

var a = new XmlDocument();
var b = new XmlDocument();

a.LoadXml("<root  foo='bar'  />");
b.LoadXml("<root foo='bar'/>");

Debug.Assert(a.OuterXml == b.OuterXml);

Ответ 4

Л.Бушкин прав, это не тривиально. Поскольку XML - это строковые данные, вы можете технически выполнить хэш содержимого и сравнить их, но на это будут влиять такие вещи, как пробелы.

Вы можете выполнить структурированный diff (также называемый XML diffgram) между двумя документами и сравнить результаты. Например, такие данные .NET отслеживают изменения, например.

Кроме того, вам придется проходить через DOM и сравнивать элементы, атрибуты и значения друг с другом. Если есть схема, то вам также придется учитывать позиции и т.д.