Синтаксис и применение ПреобразованиеККаноническомуXML.По умолчанию в платформе 1С:Предприятие. Описание и примеры кода.
Синтаксис
Новый ПреобразованиеККаноническомуXMLПолное описание, параметры и ограничения
ПреобразованиеККаноническомуXML.По умолчанию
ПреобразованиеККаноническомуXML (ConversionToCanonicalXML)
По умолчанию
Синтаксис:
Новый ПреобразованиеККаноническомуXML
Методическая информация
Практические примеры
Записать канонический XML в один свой временный файл и проверить очистку
Отдельный согласуемый опыт в новом стенде: уникальное временное имя, канонизация в файл, чтение реальных байтов, сравнение со строкой и удаление только этого файла. Сам справочник ничего не запускает.
Где и как запускать
Полный модуль отдельной управляемой формы; клиентское согласие и серверный опыт с одним собственным временным XML-файлом.
Подготовка
Создайте собственную новую пустую конфигурацию УчебнаяКанонизацияXML85, управляемое приложение, платформа8.5.1.1343. Не используйте production или базу с чужими обработчиками.
Обработки → ОпытXML85 → управляемая форма Форма, основная форма обработки. Для каждого урока создайте отдельную обработку либо заменяйте целиком модуль формы: три модуля ниже не вставляются друг в друга.
Создайте указанную в уроке команду с одноимённым действием и перетащите её на форму. Код — полный модуль формы; вспомогательную серверную функцию оставьте на уровне модуля.
Нажмите F7 и обновите только новый стенд. runtimeVerifiedScenarios=0: справочник проверялся статически; данный код в 1С здесь не выполнялся.
Откройте обработку через функции для технического специалиста. Клиент показывает только итоговую строку; ДокументDOM, фильтр, поток и итератор остаются на сервере.
Исходные данные заданы прямо в коде. Нет внешнего XML, DTD, сети, подписания документов или записи прикладных объектов.
Команда ПроверитьКаноническийФайл85. Добавьте реквизит РазрешитьУчебныйФайл типа Булево, исходно Ложь; покажите его флажком на форме. Без согласия кнопка не вызывает серверный опыт.
Администратор должен разрешить только учебный временный каталог учётной записи сервера стенда, исключив постороннюю запись и гонки за именем файла. Не запускайте на общей файловой площадке или в рабочем сеансе.
После собственного ручного подтверждения опыт создаст один временный XML-файл на сервере, не на компьютере тонкого клиента. Это тестовый результат, не резервная копия. В ходе подготовки справочника этот файл не создавался.
&НаКлиенте
Процедура ПроверитьКаноническийФайл85(Команда)
Если Не РазрешитьУчебныйФайл Тогда
ВызватьИсключение "Подтвердите один временный учебный файл на сервере стенда";
КонецЕсли;
Сообщить(ПроверитьСвойФайлНаСервере());
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПроверитьСвойФайлНаСервере()
Документ = Новый ДокументDOM("", "demo");
Корень = Документ.ЭлементДокумента;
Корень.УстановитьАтрибут("b", "2");
Корень.УстановитьАтрибут("a", "1");
Корень.ДобавитьДочерний(Документ.СоздатьТекстовыйУзел("A & B"));
Преобразователь = Новый ПреобразованиеККаноническомуXML;
Алгоритм = ТипКаноническогоXML.КаноническийXML1_1;
ОжидаемаяСтрока = Преобразователь.КанонизироватьВСтроку(Документ, Алгоритм);
ПутьСвоегоФайла = ПолучитьИмяВременногоФайла("xml");
СвойФайл = Новый Файл(ПутьСвоегоФайла);
Если СвойФайл.Существует() Тогда
ВызватьИсключение "Отказ: даже уникальное имя не должно указывать на существующий файл";
КонецЕсли;
ОшибкаОпыта = "";
Попытка
Преобразователь.КанонизироватьВФайл(Документ, ПутьСвоегоФайла, Алгоритм);
ДанныеФайла = Новый ДвоичныеДанные(ПутьСвоегоФайла);
СтрокаФайла = ПолучитьСтрокуИзДвоичныхДанных(ДанныеФайла, КодировкаТекста.UTF8);
Если СтрокаФайла <> ОжидаемаяСтрока Тогда
ВызватьИсключение "Содержимое своего файла отличается от канонической строки";
КонецЕсли;
Исключение
ОшибкаОпыта = ОписаниеОшибки();
КонецПопытки;
Попытка
Если СвойФайл.Существует() Тогда
УдалитьФайлы(ПутьСвоегоФайла);
КонецЕсли;
Если СвойФайл.Существует() Тогда
ВызватьИсключение "Свой временный файл ещё существует";
КонецЕсли;
Исключение
ОшибкаОпыта = ОшибкаОпыта + " Не подтверждено удаление своего временного файла: " + ОписаниеОшибки();
КонецПопытки;
Если ОшибкаОпыта <> "" Тогда
ВызватьИсключение ОшибкаОпыта;
КонецЕсли;
Возврат "Свой канонический файл совпал со строкой и удалён. Резервные копии не создавались.";
КонецФункцииРазбор по шагам
Собственный demo создаётся в памяти; строковая канонизация служит ожидаемым результатом для файлового варианта с тем же алгоритмом.
ПолучитьИмяВременногоФайла даёт уникальное имя, но не создаёт файл. Если по этому имени уже что-то существует, опыт отказывается до записи и не удаляет найденный объект.
КанонизироватьВФайл получает только сгенерированное имя, не пользовательский путь, каталог или маску. Новый ДвоичныеДанные читает фактически записанные байты.
Байты декодируются UTF-8 и полностью сравниваются с ожидаемой строкой. Ошибка записи, чтения или сравнения сохраняется, но не пропускает попытку очистки.
УдалитьФайлы получает только полное имя своего единственного файла. Отдельно проверяется отсутствие файла после очистки; ошибки очистки добавляются к исходной ошибке.
Успех возвращается лишь после совпадения результата и подтверждённой очистки. Учебная база и каталог не удаляются.
Как проверить результат
Без установленного флажка серверная функция не вызывается.
Содержимое созданного файла равно результату КанонизироватьВСтроку для того же DOM и алгоритма.
После успеха своего временного файла нет. При отказе файловой системы выводится исключение, а не ложное сообщение об очистке.
Отказ при уже существующем имени находится перед записью и удалением; чужой файл код не принимает как свой.
Ожидаемый результат
Свой канонический файл совпал со строкой и удалён. Резервные копии не создавались.
На что обратить внимание
УдалитьФайлы без маски может удалить каталог, если передать каталог. В этом уроке допускается только полное сгенерированное имя XML-файла; не заменяйте его путём к каталогу.
Проверка Существует не является атомарным резервированием имени. Обязателен закрытый учебный временный каталог без чужой записи; этот код не предназначен для враждебной общей файловой среды.
На сервере пути и права относятся к серверной учётной записи. Клиентский путь C: не переносится на сервер автоматически.
Ошибка очистки требует осмотра именно показанного учебного окружения. Не пытайтесь очищать все временные каталоги по маске.
Никакой реальный файл при подготовке этого урока не создавался и не удалялся. Ручной запуск допускается только после F7 и согласия в собственном стенде.
Этот вариант нужен для знакомства с файловым API. Для обычного сравнения используйте предыдущий урок в памяти, без файловых прав.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Сравнить собственный 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 требует своих контрольных значений.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.