ПреобразованиеККаноническомуXML.По умолчанию

Конструкторы

Синтаксис и применение ПреобразованиеККаноническомуXML.По умолчанию в платформе 1С:Предприятие. Описание и примеры кода.

Синтаксис

Новый ПреобразованиеККаноническомуXML
Полное описание, параметры и ограничения

ПреобразованиеККаноническомуXML.По умолчанию

ПреобразованиеККаноническомуXML (ConversionToCanonicalXML)

По умолчанию

Синтаксис:
Новый ПреобразованиеККаноническомуXML
Методическая информация

Практические примеры

Записать канонический XML в один свой временный файл и проверить очистку

Отдельный согласуемый опыт в новом стенде: уникальное временное имя, канонизация в файл, чтение реальных байтов, сравнение со строкой и удаление только этого файла. Сам справочник ничего не запускает.

Где и как запускать

Полный модуль отдельной управляемой формы; клиентское согласие и серверный опыт с одним собственным временным XML-файлом.

Подготовка

  1. Создайте собственную новую пустую конфигурацию УчебнаяКанонизацияXML85, управляемое приложение, платформа8.5.1.1343. Не используйте production или базу с чужими обработчиками.

  2. Обработки → ОпытXML85 → управляемая форма Форма, основная форма обработки. Для каждого урока создайте отдельную обработку либо заменяйте целиком модуль формы: три модуля ниже не вставляются друг в друга.

  3. Создайте указанную в уроке команду с одноимённым действием и перетащите её на форму. Код — полный модуль формы; вспомогательную серверную функцию оставьте на уровне модуля.

  4. Нажмите F7 и обновите только новый стенд. runtimeVerifiedScenarios=0: справочник проверялся статически; данный код в 1С здесь не выполнялся.

  5. Откройте обработку через функции для технического специалиста. Клиент показывает только итоговую строку; ДокументDOM, фильтр, поток и итератор остаются на сервере.

  6. Исходные данные заданы прямо в коде. Нет внешнего XML, DTD, сети, подписания документов или записи прикладных объектов.

  7. Команда ПроверитьКаноническийФайл85. Добавьте реквизит РазрешитьУчебныйФайл типа Булево, исходно Ложь; покажите его флажком на форме. Без согласия кнопка не вызывает серверный опыт.

  8. Администратор должен разрешить только учебный временный каталог учётной записи сервера стенда, исключив постороннюю запись и гонки за именем файла. Не запускайте на общей файловой площадке или в рабочем сеансе.

  9. После собственного ручного подтверждения опыт создаст один временный XML-файл на сервере, не на компьютере тонкого клиента. Это тестовый результат, не резервная копия. В ходе подготовки справочника этот файл не создавался.

&НаКлиенте
Процедура ПроверитьКаноническийФайл85(Команда)
    Если Не РазрешитьУчебныйФайл Тогда
        ВызватьИсключение "Подтвердите один временный учебный файл на сервере стенда";
    КонецЕсли;
    Сообщить(ПроверитьСвойФайлНаСервере());
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПроверитьСвойФайлНаСервере()
    Документ = Новый ДокументDOM("", "demo");
    Корень = Документ.ЭлементДокумента;
    Корень.УстановитьАтрибут("b", "2");
    Корень.УстановитьАтрибут("a", "1");
    Корень.ДобавитьДочерний(Документ.СоздатьТекстовыйУзел("A & B"));
    Преобразователь = Новый ПреобразованиеККаноническомуXML;
    Алгоритм = ТипКаноническогоXML.КаноническийXML1_1;
    ОжидаемаяСтрока = Преобразователь.КанонизироватьВСтроку(Документ, Алгоритм);
    ПутьСвоегоФайла = ПолучитьИмяВременногоФайла("xml");
    СвойФайл = Новый Файл(ПутьСвоегоФайла);
    Если СвойФайл.Существует() Тогда
        ВызватьИсключение "Отказ: даже уникальное имя не должно указывать на существующий файл";
    КонецЕсли;
    ОшибкаОпыта = "";
    Попытка
        Преобразователь.КанонизироватьВФайл(Документ, ПутьСвоегоФайла, Алгоритм);
        ДанныеФайла = Новый ДвоичныеДанные(ПутьСвоегоФайла);
        СтрокаФайла = ПолучитьСтрокуИзДвоичныхДанных(ДанныеФайла, КодировкаТекста.UTF8);
        Если СтрокаФайла <> ОжидаемаяСтрока Тогда
            ВызватьИсключение "Содержимое своего файла отличается от канонической строки";
        КонецЕсли;
    Исключение
        ОшибкаОпыта = ОписаниеОшибки();
    КонецПопытки;
    Попытка
        Если СвойФайл.Существует() Тогда
            УдалитьФайлы(ПутьСвоегоФайла);
        КонецЕсли;
        Если СвойФайл.Существует() Тогда
            ВызватьИсключение "Свой временный файл ещё существует";
        КонецЕсли;
    Исключение
        ОшибкаОпыта = ОшибкаОпыта + " Не подтверждено удаление своего временного файла: " + ОписаниеОшибки();
    КонецПопытки;
    Если ОшибкаОпыта <> "" Тогда
        ВызватьИсключение ОшибкаОпыта;
    КонецЕсли;
    Возврат "Свой канонический файл совпал со строкой и удалён. Резервные копии не создавались.";
КонецФункции

Разбор по шагам

  1. Собственный demo создаётся в памяти; строковая канонизация служит ожидаемым результатом для файлового варианта с тем же алгоритмом.

  2. ПолучитьИмяВременногоФайла даёт уникальное имя, но не создаёт файл. Если по этому имени уже что-то существует, опыт отказывается до записи и не удаляет найденный объект.

  3. КанонизироватьВФайл получает только сгенерированное имя, не пользовательский путь, каталог или маску. Новый ДвоичныеДанные читает фактически записанные байты.

  4. Байты декодируются UTF-8 и полностью сравниваются с ожидаемой строкой. Ошибка записи, чтения или сравнения сохраняется, но не пропускает попытку очистки.

  5. УдалитьФайлы получает только полное имя своего единственного файла. Отдельно проверяется отсутствие файла после очистки; ошибки очистки добавляются к исходной ошибке.

  6. Успех возвращается лишь после совпадения результата и подтверждённой очистки. Учебная база и каталог не удаляются.

Как проверить результат

  1. Без установленного флажка серверная функция не вызывается.

  2. Содержимое созданного файла равно результату КанонизироватьВСтроку для того же DOM и алгоритма.

  3. После успеха своего временного файла нет. При отказе файловой системы выводится исключение, а не ложное сообщение об очистке.

  4. Отказ при уже существующем имени находится перед записью и удалением; чужой файл код не принимает как свой.

Ожидаемый результат

Свой канонический файл совпал со строкой и удалён. Резервные копии не создавались.

На что обратить внимание

  1. УдалитьФайлы без маски может удалить каталог, если передать каталог. В этом уроке допускается только полное сгенерированное имя XML-файла; не заменяйте его путём к каталогу.

  2. Проверка Существует не является атомарным резервированием имени. Обязателен закрытый учебный временный каталог без чужой записи; этот код не предназначен для враждебной общей файловой среды.

  3. На сервере пути и права относятся к серверной учётной записи. Клиентский путь C: не переносится на сервер автоматически.

  4. Ошибка очистки требует осмотра именно показанного учебного окружения. Не пытайтесь очищать все временные каталоги по маске.

  5. Никакой реальный файл при подготовке этого урока не создавался и не удалялся. Ручной запуск допускается только после F7 и согласия в собственном стенде.

  6. Этот вариант нужен для знакомства с файловым API. Для обычного сравнения используйте предыдущий урок в памяти, без файловых прав.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Сравнить собственный XML после канонизации в строку и в поток

Два новых документа с одинаковыми данными и разным порядком установки атрибутов сравниваются в каноническом виде. Поток проверяется против строки, а намеренное изменение b должно обнаружиться.

Где и как запускать

Полный модуль управляемой формы; серверная функция без контекста, два собственных DOM и поток в памяти.

Подготовка

  1. Создайте собственную новую пустую конфигурацию УчебнаяКанонизацияXML85, управляемое приложение, платформа8.5.1.1343. Не используйте production или базу с чужими обработчиками.

  2. Обработки → ОпытXML85 → управляемая форма Форма, основная форма обработки. Для каждого урока создайте отдельную обработку либо заменяйте целиком модуль формы: три модуля ниже не вставляются друг в друга.

  3. Создайте указанную в уроке команду с одноимённым действием и перетащите её на форму. Код — полный модуль формы; вспомогательную серверную функцию оставьте на уровне модуля.

  4. Нажмите F7 и обновите только новый стенд. runtimeVerifiedScenarios=0: справочник проверялся статически; данный код в 1С здесь не выполнялся.

  5. Откройте обработку через функции для технического специалиста. Клиент показывает только итоговую строку; ДокументDOM, фильтр, поток и итератор остаются на сервере.

  6. Исходные данные заданы прямо в коде. Нет внешнего XML, DTD, сети, подписания документов или записи прикладных объектов.

  7. Команда и кнопка ПроверитьКанонизацию85. Реквизиты формы не требуются: весь опыт создаётся в серверной функции.

  8. Проверьте сначала исходный код, затем измените значение 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 &amp; B</demo>" Тогда
        ВызватьИсключение "Проверьте ожидаемую каноническую форму своего простого документа";
    КонецЕсли;

    Поток = Новый ПотокВПамяти;
    Попытка
        Преобразователь.КанонизироватьВПоток(Первый, Поток, Алгоритм);
        ДанныеПотока = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    Исключение
        ОшибкаКанонизации = ОписаниеОшибки();
        Попытка
            Поток.Закрыть();
        Исключение
            ОшибкаКанонизации = ОшибкаКанонизации + " Ошибка закрытия: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаКанонизации;
    КонецПопытки;
    КанонПотока = ПолучитьСтрокуИзДвоичныхДанных(ДанныеПотока, КодировкаТекста.UTF8);
    Если КанонПотока <> КанонПервого Тогда
        ВызватьИсключение "Канонизация в поток должна дать тот же UTF-8 текст";
    КонецЕсли;

    КореньВторого.УстановитьАтрибут("b", "3");
    Измененный = Преобразователь.КанонизироватьВСтроку(Второй, Алгоритм);
    Если Измененный = КанонПервого Тогда
        ВызватьИсключение "Изменение данных должно изменить каноническую строку";
    КонецЕсли;
    Возврат "Строка и поток совпали: " + КанонПервого + "; изменение b обнаружено. Файлы не создавались.";
КонецФункции

Разбор по шагам

  1. Первый и Второй — самостоятельные собственные ДокументDOM. Корни demo содержат атрибуты a=1, b=2 и один текстовый узел A & B; порядок добавления атрибутов противоположный.

  2. Новый ПреобразованиеККаноническомуXML создаёт реальный преобразователь без неизвестного объекта-источника. Для всех вызовов явно выбран один алгоритм КаноническийXML1_1.

  3. КанонизироватьВСтроку вызывается для обоих документов. Сравниваются полные строки, затем проверяется ожидаемая форма простого собственного XML с экранированным амперсандом.

  4. КанонизироватьВПоток записывает первый документ в новый ПотокВПамяти. ЗакрытьИПолучитьДвоичныеДанные завершает поток и отдаёт его реальные байты; UTF-8 декодируется явно.

  5. Текст потока сравнивается с канонической строкой. При ошибке записи отдельно предпринимается закрытие потока, а обе ошибки сохраняются в исключении.

  6. Второй документ меняется на b=3 и канонизируется заново. Несовпадение подтверждает, что алгоритм не скрывает изменение данных. Возвращается только строка итогов.

Как проверить результат

  1. Одинаковые данные дают одинаковую строку независимо от порядка установки a и b.

  2. Ожидается <demo a="1" b="2">A &amp; B</demo>; XML-декларация не входит в эту каноническую строку.

  3. UTF-8 данные потока дают ту же строку; ни один файл не создаётся.

  4. После изменения b=3 каноническая строка отличается от исходной. Повторный запуск создаёт новые документы.

Ожидаемый результат

Строка и поток совпадают; изменение b обнаружено. Канонизация выполняется полностью в памяти.

На что обратить внимание

  1. Канонизация — не красивое форматирование, не шифрование, не подпись и не сравнение бизнес-смысла документов.

  2. Сравнивайте одинаковый алгоритм, одинаковый набор узлов и одинаковые настройки включения пространств имён. В уроке фильтр XPath и список префиксов не используются.

  3. Текстовые пробелы внутри XML являются данными. Не добавляйте форматирующие отступы в собственное дерево и не ожидайте, что канонизация их удалит.

  4. Нельзя заменить выбранный алгоритм старым КаноническаяЗаписьXML или КаноническийDOM и предположить одинаковое поведение: эти объекты не рекомендуются с8.3.9.

  5. После ЗакрытьИПолучитьДвоичныеДанные поток закрыт; последующих операций с ним нет. DOM не возвращается в тонкий клиент.

  6. Ожидаемая строка относится только к этому простому документу без пространств имён, комментариев и DTD. Другой XML требует своих контрольных значений.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.