Как в 1С сформировать XML-файл с вложенной секцией CDATA для передачи данных через веб-сервисы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними системами (особенно в авиационной сфере, логистике или при работе с банковскими API) программисты часто сталкиваются с необходимостью формирования сложных SOAP-сообщений. Одной из специфических задач является вставка целого XML-документа внутрь другого XML-файла в виде секции CDATA. В этой статье мы разберем, как правильно реализовать такой механизм, используя стандартные средства платформы 1С:Предприятие 8.3.

Постановка задачи и анализ структуры

Рассмотрим ситуацию на примере формирования сообщения XFFM (Flight Manifest) стандарта IATA Cargo-XML. Внешний сервис ожидает стандартную SOAP-оболочку (Envelope), внутри которой в одном из элементов (например, api2:xffm) должен находиться основной блок данных, экранированный секцией CDATA. Это делается для того, чтобы парсер основной XML-структуры не пытался интерпретировать вложенные теги как часть основного документа.

Проанализируем типичную структуру такого сообщения:

  1. SOAP-конверт: Внешние теги soapenv:Envelope, soapenv:Header и soapenv:Body.
  2. Метод сервиса: Тег api2:sendMessageXFFM.
  3. Секция CDATA: Вложенный XML-документ с данными о манифесте рейса, который передается как текстовый блок.

Способ 1: Использование двух объектов ЗаписьXML (Рекомендуемый)

Самый надежный способ сформировать такой файл — это разделить процесс на два этапа. Сначала мы создаем внутренний XML-документ, преобразуем его в строку, а затем записываем эту строку в основной XML-файл через специальный метод ЗаписатьСекциюCDATA(). Разберем этот процесс по шагам.

Шаг 1: Формируем внутреннее сообщение в строку

Для этого создадим временный объект ЗаписьXML, который будет писать данные в память (в строку), а не сразу в файл.


// Создаем объект для записи внутреннего XML
ЗаписьВнутренняя = Новый ЗаписьXML;
ЗаписьВнутренняя.УстановитьСтроку("UTF-8");

// Записываем структуру внутреннего сообщения (например, манифест рейса)
ЗаписьВнутренняя.ЗаписатьНачалоЭлемента("ns0:FlightManifest", "http://www.iata.org/IATA/2005/00/CargoXML");
ЗаписьВнутренняя.ЗаписатьНачалоЭлемента("MessageHeader");
ЗаписьВнутренняя.ЗаписатьТекст("PMD_240822162004");
ЗаписьВнутренняя.ЗаписатьКонецЭлемента(); // MessageHeader
// ... добавление остальных узлов манифеста ...
ЗаписьВнутренняя.ЗаписатьКонецЭлемента(); // FlightManifest

// Получаем сформированный XML в виде строки
ТекстВнутреннегоXML = ЗаписьВнутренняя.Закрыть();

Шаг 2: Формируем основной SOAP-конверт

Теперь создаем основной объект ЗаписьXML и вставляем туда полученную ранее строку.


Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку("UTF-8");
Запись.ЗаписатьОбъявлениеXML();

// Формируем SOAP-оболочку
Запись.ЗаписатьНачалоЭлемента("soapenv:Envelope");
Запись.ЗаписатьАтрибут("xmlns:soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
Запись.ЗаписатьАтрибут("xmlns:api2", "http://api.example.com/v2");

Запись.ЗаписатьНачалоЭлемента("soapenv:Body");
Запись.ЗаписатьНачалоЭлемента("api2:sendMessageXFFM");

// Записываем статические параметры
Запись.ЗаписатьНачалоЭлемента("api2:airline");
Запись.ЗаписатьТекст("PMD");
Запись.ЗаписатьКонецЭлемента();

// ВАЖНЫЙ МОМЕНТ: Записываем вложенный XML как CDATA
Запись.ЗаписатьНачалоЭлемента("api2:xffm");
Запись.ЗаписатьСекциюCDATA(ТекстВнутреннегоXML); 
Запись.ЗаписатьКонецЭлемента(); // api2:xffm

Запись.ЗаписатьКонецЭлемента(); // api2:sendMessageXFFM
Запись.ЗаписатьКонецЭлемента(); // soapenv:Body
Запись.ЗаписатьКонецЭлемента(); // soapenv:Envelope

Результат = Запись.Закрыть();

Особенности работы с CDATA в 1С

Проанализируем технические нюансы, которые могут возникнуть при использовании метода ЗаписатьСекциюCDATA():

Альтернативный подход: Использование XDTO

Если у вас есть XSD-схема для вложенного сообщения (например, схема манифеста IATA), использование XDTO-пакетов будет более профессиональным решением. Проанализируем преимущества этого метода:

  1. Автоматическая валидация: 1С не даст создать XML, не соответствующий схеме (ошибки в типах данных или пропущенные обязательные поля).
  2. Управление пространствами имен: Вам не придется вручную прописывать префиксы типа ns0:, система расставит их автоматически согласно URI из схемы.
  3. Сериализация в строку: Объект XDTO легко превращается в строку, которую затем можно передать в ЗаписатьСекциюCDATA().

Пример получения строки из XDTO для вставки в CDATA:


// Предположим, у нас есть заполненный объект XDTO "МанифестОбъект"
ЗаписьXDTO = Новый ЗаписьXML;
ЗаписьXDTO.УстановитьСтроку();
ФабрикаXDTO.Записать(ЗаписьXDTO, МанифестОбъект);
СтрокаДляCDATA = ЗаписьXDTO.Закрыть();

// Далее используем СтрокаДляCDATA в основном коде

Почему не стоит использовать WS-ссылки в данном случае?

Хотя в 1С есть механизм WS-ссылки для автоматической работы с SOAP, в ситуациях с CDATA он часто оказывается бесполезен. Выясним причину: большинство веб-сервисов, использующих такой формат, объявляют параметр входа как обычную строку (string). Если вы импортируете WSDL такого сервиса, 1С предложит вам передать просто текст. Чтобы этот текст был валидным XML-документом, его всё равно придется формировать вручную одним из способов, описанных выше.

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

Рекомендации по отладке

При отладке формирования сложных XML-структур мы рекомендуем использовать форматированный вывод. Для этого при инициализации ЗаписьXML можно использовать параметры:


ПараметрыЗаписи = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина, Истина, Символы.Таб);
Запись.УстановитьСтроку(ПараметрыЗаписи);

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

Таким образом, комбинируя ручную запись через ЗаписьXML и использование CDATA, можно реализовать интеграцию с самыми сложными зарубежными и ведомственными системами, соблюдая все требования протоколов передачи данных.

← На главную