Преобразует документ DOM к каноническому виду.
Синтаксис
КанонизироватьВСтроку(<ДокументDOM>, <ТипКаноническогоXML>, <ФильтрXPath>, <ПрефиксыДляВключения>)Полное описание, параметры и ограничения
ПреобразованиеККаноническомуXML.КанонизироватьВСтроку (ConversionToCanonicalXML.CanonicalizeToString)
ПреобразованиеККаноническомуXML (ConversionToCanonicalXML)
КанонизироватьВСтроку (CanonicalizeToString)
Доступен, начиная с версии 8.3.9.
Синтаксис:
КанонизироватьВСтроку(<ДокументDOM>, <ТипКаноническогоXML>, <ФильтрXPath>, <ПрефиксыДляВключения>)
Параметры:
<ДокументDOM> (обязательный)
Тип: ДокументDOM.
Документ DOM, который нужно записать в каноническом виде.
<ТипКаноническогоXML> (необязательный)
Тип: ТипКаноническогоXML.
Тип алгоритма приведения к каноническому виду.
Значение по умолчанию: КаноническийXML1_1.
<ФильтрXPath> (необязательный)
Тип: РезультатXPath, Строка.
Если передана Строка, то перед преобразованием к каноническому виду будет выполнен запрос XPath из этой строки, и каноническая форма XML-документа будет содержать только результирующее подмножество документа.
Если передан объект типа РезультатXPath, то к каноническому виду будет преобразовано подмножество узлов из переданного параметра.
Значение по умолчанию: Неопределено.
<ПрефиксыДляВключения> (необязательный)
Тип: Строка.
Содержит список префиксов пространств имен для включения в формате: "Префикс1 Префикс2", и так далее.
Префиксы для включения используются в алгоритме исключающего канонического XML (см. стандарт W3C Exclusive XML Canonicalization - https://www.w3.org/TR/xml-exc-c14n/).
В остальных случаях параметр игнорируется.
Значение по умолчанию: Неопределено.
Возвращаемое значение:
Тип: Строка.
Результат возвращается в виде строки.
Описание:
Преобразует документ DOM к каноническому виду.
Доступность:
Тонкий клиент, сервер, толстый клиент, внешнее соединение.
Использование в версии:
Доступен, начиная с версии 8.3.9.
Методическая информация
Практические примеры
Сравнить собственный XML после канонизации в строку и в поток
Два новых документа с одинаковыми данными и разным порядком установки атрибутов сравниваются в каноническом виде. Поток проверяется против строки, а намеренное изменение b должно обнаружиться.
Где и как запускать
Полный модуль управляемой формы; серверная функция без контекста, два собственных DOM и поток в памяти.
Подготовка
Создайте собственную новую пустую конфигурацию УчебнаяКанонизацияXML85, управляемое приложение, платформа8.5.1.1343. Не используйте production или базу с чужими обработчиками.
Обработки → ОпытXML85 → управляемая форма Форма, основная форма обработки. Для каждого урока создайте отдельную обработку либо заменяйте целиком модуль формы: три модуля ниже не вставляются друг в друга.
Создайте указанную в уроке команду с одноимённым действием и перетащите её на форму. Код — полный модуль формы; вспомогательную серверную функцию оставьте на уровне модуля.
Нажмите F7 и обновите только новый стенд. runtimeVerifiedScenarios=0: справочник проверялся статически; данный код в 1С здесь не выполнялся.
Откройте обработку через функции для технического специалиста. Клиент показывает только итоговую строку; ДокументDOM, фильтр, поток и итератор остаются на сервере.
Исходные данные заданы прямо в коде. Нет внешнего XML, DTD, сети, подписания документов или записи прикладных объектов.
Команда и кнопка ПроверитьКанонизацию85. Реквизиты формы не требуются: весь опыт создаётся в серверной функции.
Проверьте сначала исходный код, затем измените значение b второго документа на этапе создания: контроль равенства должен остановить опыт. Не ослабляйте исключения ради сообщения об успехе.
&НаКлиенте
Процедура ПроверитьКанонизацию85(Команда)
Сообщить(КанонизироватьСвоиДокументы());
КонецПроцедуры
&НаСервереБезКонтекста
Функция КанонизироватьСвоиДокументы()
Первый = Новый ДокументDOM("", "demo");
КореньПервого = Первый.ЭлементДокумента;
КореньПервого.УстановитьАтрибут("b", "2");
КореньПервого.УстановитьАтрибут("a", "1");
КореньПервого.ДобавитьДочерний(Первый.СоздатьТекстовыйУзел("A & B"));
Второй = Новый ДокументDOM("", "demo");
КореньВторого = Второй.ЭлементДокумента;
КореньВторого.УстановитьАтрибут("a", "1");
КореньВторого.УстановитьАтрибут("b", "2");
КореньВторого.ДобавитьДочерний(Второй.СоздатьТекстовыйУзел("A & B"));
Преобразователь = Новый ПреобразованиеККаноническомуXML;
Алгоритм = ТипКаноническогоXML.КаноническийXML1_1;
КанонПервого = Преобразователь.КанонизироватьВСтроку(Первый, Алгоритм);
КанонВторого = Преобразователь.КанонизироватьВСтроку(Второй, Алгоритм);
Если КанонПервого <> КанонВторого Тогда
ВызватьИсключение "Одинаковые данные с разным порядком установки атрибутов должны совпасть";
КонецЕсли;
Если КанонПервого <> "<demo a=""1"" b=""2"">A & B</demo>" Тогда
ВызватьИсключение "Проверьте ожидаемую каноническую форму своего простого документа";
КонецЕсли;
Поток = Новый ПотокВПамяти;
Попытка
Преобразователь.КанонизироватьВПоток(Первый, Поток, Алгоритм);
ДанныеПотока = Поток.ЗакрытьИПолучитьДвоичныеДанные();
Исключение
ОшибкаКанонизации = ОписаниеОшибки();
Попытка
Поток.Закрыть();
Исключение
ОшибкаКанонизации = ОшибкаКанонизации + " Ошибка закрытия: " + ОписаниеОшибки();
КонецПопытки;
ВызватьИсключение ОшибкаКанонизации;
КонецПопытки;
КанонПотока = ПолучитьСтрокуИзДвоичныхДанных(ДанныеПотока, КодировкаТекста.UTF8);
Если КанонПотока <> КанонПервого Тогда
ВызватьИсключение "Канонизация в поток должна дать тот же UTF-8 текст";
КонецЕсли;
КореньВторого.УстановитьАтрибут("b", "3");
Измененный = Преобразователь.КанонизироватьВСтроку(Второй, Алгоритм);
Если Измененный = КанонПервого Тогда
ВызватьИсключение "Изменение данных должно изменить каноническую строку";
КонецЕсли;
Возврат "Строка и поток совпали: " + КанонПервого + "; изменение b обнаружено. Файлы не создавались.";
КонецФункцииРазбор по шагам
Первый и Второй — самостоятельные собственные ДокументDOM. Корни demo содержат атрибуты a=1, b=2 и один текстовый узел A & B; порядок добавления атрибутов противоположный.
Новый ПреобразованиеККаноническомуXML создаёт реальный преобразователь без неизвестного объекта-источника. Для всех вызовов явно выбран один алгоритм КаноническийXML1_1.
КанонизироватьВСтроку вызывается для обоих документов. Сравниваются полные строки, затем проверяется ожидаемая форма простого собственного XML с экранированным амперсандом.
КанонизироватьВПоток записывает первый документ в новый ПотокВПамяти. ЗакрытьИПолучитьДвоичныеДанные завершает поток и отдаёт его реальные байты; UTF-8 декодируется явно.
Текст потока сравнивается с канонической строкой. При ошибке записи отдельно предпринимается закрытие потока, а обе ошибки сохраняются в исключении.
Второй документ меняется на b=3 и канонизируется заново. Несовпадение подтверждает, что алгоритм не скрывает изменение данных. Возвращается только строка итогов.
Как проверить результат
Одинаковые данные дают одинаковую строку независимо от порядка установки a и b.
Ожидается <demo a="1" b="2">A & B</demo>; XML-декларация не входит в эту каноническую строку.
UTF-8 данные потока дают ту же строку; ни один файл не создаётся.
После изменения b=3 каноническая строка отличается от исходной. Повторный запуск создаёт новые документы.
Ожидаемый результат
Строка и поток совпадают; изменение b обнаружено. Канонизация выполняется полностью в памяти.
На что обратить внимание
Канонизация — не красивое форматирование, не шифрование, не подпись и не сравнение бизнес-смысла документов.
Сравнивайте одинаковый алгоритм, одинаковый набор узлов и одинаковые настройки включения пространств имён. В уроке фильтр XPath и список префиксов не используются.
Текстовые пробелы внутри XML являются данными. Не добавляйте форматирующие отступы в собственное дерево и не ожидайте, что канонизация их удалит.
Нельзя заменить выбранный алгоритм старым КаноническаяЗаписьXML или КаноническийDOM и предположить одинаковое поведение: эти объекты не рекомендуются с8.3.9.
После ЗакрытьИПолучитьДвоичныеДанные поток закрыт; последующих операций с ним нет. DOM не возвращается в тонкий клиент.
Ожидаемая строка относится только к этому простому документу без пространств имён, комментариев и DTD. Другой XML требует своих контрольных значений.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.