Как сформировать XML с нестандартным заголовком и структурой в 1С

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

При интеграции 1С с внешними системами, государственными порталами или сервисами электронного документооборота (ЭДО) разработчики часто сталкиваются с жесткими требованиями к формату XML. Стандартный объект ЗаписьXML в 1С отлично справляется с типовыми задачами, но иногда его возможностей недостаточно. Например, когда требуется вставить специфическое объявление DOCTYPE, нестандартные инструкции обработки или когда структура файла настолько сложна, что код на ЗаписьXML становится нечитаемым.

В этой статье мы подробно разберем несколько подходов к решению этой задачи: от гибкого использования текстовых шаблонов в макетах до профессиональной работы с XDTO и DOM. Мы проанализируем, как сделать код прозрачным, а процесс формирования файла — максимально надежным.

Метод 1: Использование текстовых шаблонов в макетах конфигурации

Это один из самых популярных способов среди опытных разработчиков, когда нужно быстро создать сложную "простыню" XML. Основная идея заключается в том, чтобы хранить структуру XML в текстовом макете конфигурации, используя специальные маркеры (например, %FILEID, %DOCNUM) для последующей замены на реальные данные.

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

Шаг 1. Создание макета. Создайте в обработке или общем макете объект типа "Текстовый документ". Вставьте туда ваш XML-код. Для повторяющихся частей (например, строк товаров) лучше создать отдельные макеты или секции.

Шаг 2. Экранирование спецсимволов. XML критичен к спецсимволам в значениях атрибутов (например, символ & в названии контрагента сломает файл). Нам понадобится вспомогательная функция для подготовки строк:


Функция СтрокаXML_Безопасная(ВхСтрока)
    Результат = ВхСтрока;
    Результат = СтрЗаменить(Результат, "&", "&");
    Результат = СтрЗаменить(Результат, "<", "<");
    Результат = СтрЗаменить(Результат, ">", ">");
    Результат = СтрЗаменить(Результат, """", """);
    Результат = СтрЗаменить(Результат, "'", "'");
    Возврат Результат;
КонецФункции

Шаг 3. Заполнение шаблона данными. Проанализируем процесс подстановки. Мы используем структуру для хранения параметров и последовательно заменяем маркеры в тексте макета.


Процедура СформироватьФайлПоШаблону()
    // Получаем текст основного тела из макета
    ТекстШаблона = ПолучитьМакет("Макет_УПД_Тело").ПолучитьТекст();
    
    Параметры = Новый Структура;
    Параметры.Вставить("FILEID", "ИД_12345");
    Параметры.Вставить("SENDERID", "ORG_7701");
    Параметры.Вставить("DOCNUM", СокрЛП(Объект.Номер));
    
    // Заменяем простые параметры
    Для Каждого Параметр Из Параметры Цикл
        ТекстШаблона = СтрЗаменить(ТекстШаблона, "%" + Параметр.Ключ, СтрокаXML_Безопасная(Параметр.Значение));
    КонецЦикла;
    
    // Формируем табличную часть через отдельный шаблон
    ТекстТаблицы = "";
    ШаблонСтроки = ПолучитьМакет("Макет_УПД_Строка").ПолучитьТекст();
    
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        ТекСтрока = ШаблонСтроки;
        ТекСтрока = СтрЗаменить(ТекСтрока, "%ITEMNAME", СтрокаXML_Безопасная(СтрокаТЧ.Номенклатура.Наименование));
        ТекСтрока = СтрЗаменить(ТекСтрока, "%QTY", XMLСтрока(СтрокаТЧ.Количество));
        ТекстТаблицы = ТекстТаблицы + ТекСтрока + Символы.ПС;
    КонецЦикла;
    
    // Вставляем готовую таблицу в основной шаблон
    ТекстШаблона = СтрЗаменить(ТекстШаблона, "%GOODSTABLE", ТекстТаблицы);
    
    // Записываем результат на диск
    Запись = Новый ЗаписьТекста("C:\Temp\result.xml", КодировкаТекста.UTF8, , Ложь);
    Запись.Записать(ТекстШаблона);
    Запись.Закрыть();
КонецПроцедуры

Важное примечание: При использовании этого метода обратите внимание на параметр ИспользованиеByteOrderMark в объекте ЗаписьТекста. Если внешняя система не принимает файлы с меткой BOM (маркер последовательности байтов), обязательно установите значение ИспользованиеByteOrderMark.НеИспользовать.

Метод 2: Комбинированная запись (ЗаписьXML + ЗаписьТекста)

Если вам нужно использовать преимущества ЗаписьXML (автоматическое управление закрытием тегов и контроль структуры), но при этом необходимо добавить свой заголовок, рассмотрим комбинированный подход. Вы можете сначала записать в файл произвольный текст (заголовок), а затем продолжить работу через стандартный объект.

Проанализируем пример использования метода ЗаписатьБезОбработки(), который есть у объекта ЗаписьXML. Этот метод позволяет вставить строку "как есть" в поток записи.


Процедура ЗаписатьСКастомнымЗаголовком()
    Запись = Новый ЗаписьXML;
    Запись.ОткрытьФайл("C:\Temp\custom.xml", "UTF-8");
    
    // Вставляем свое объявление или DOCTYPE
    Запись.ЗаписатьБезОбработки("<!DOCTYPE MyRoot SYSTEM ""my.dtd"">" + Символы.ПС);
    
    // Дальше работаем стандартно
    Запись.ЗаписатьНачалоЭлемента("Root");
    Запись.ЗаписатьАтрибут("Версия", "1.0");
    
    Запись.ЗаписатьНачалоЭлемента("Data");
    Запись.ЗаписатьТекст("Пример данных");
    Запись.ЗаписатьКонецЭлемента(); // Data
    
    Запись.ЗаписатьКонецЭлемента(); // Root
    Запись.Закрыть();
КонецПроцедуры

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

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

Выясним причину, по которой многие выбирают XDTO (XML Data Transfer Objects). Если у вас есть XSD-схема целевого файла, XDTO — это самый надежный вариант. Платформа сама проконтролирует типы данных, порядок следования узлов и обязательность заполнения атрибутов.

Разберем процесс по шагам:

  1. Импорт схемы: Загрузите XSD-схему в конфигурацию как "Пакет XDTO".
  2. Создание объекта: Используйте ФабрикаXDTO.Создать() для создания структуры документа в памяти.
  3. Заполнение данных: Работа с объектом XDTO похожа на работу со Структурой или СправочникомОбъектом.
  4. Сериализация: Запишите объект в файл одной командой.

Процедура ЗаписатьЧерезXDTO(ДанныеОбъекта)
    // Тип берется из вашего пакета XDTO
    ТипОбъекта = ФабрикаXDTO.Тип("http://www.my-service.ru/schema", "Документ");
    НовыйОбъект = ФабрикаXDTO.Создать(ТипОбъекта);
    
    НовыйОбъект.Номер = ДанныеОбъекта.Номер;
    НовыйОбъект.Дата = ДанныеОбъекта.Дата;
    
    // Платформа сама сериализует объект в XML
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.ОткрытьФайл("C:\Temp\xdto_result.xml");
    ФабрикаXDTO.Записать(ЗаписьXML, НовыйОбъект);
    ЗаписьXML.Закрыть();
КонецПроцедуры

Сравнение методов и рекомендации

Проанализируем ситуацию, в каких случаях какой метод эффективнее:

1. Скорость разработки и наглядность: Метод с шаблонами в макетах выигрывает, если XML-формат очень специфичен, содержит много комментариев или нестандартных вставок. Он идеален для небольших и средних файлов (например, выгрузка одного счета-фактуры).

2. Производительность: Если вам нужно выгрузить сотни тысяч строк товаров, шаблоны через СтрЗаменить могут работать медленно и потреблять много памяти, так как при каждой замене создается новая копия всей строки. В этом случае ЗаписьXML или ЗаписьТекста в потоковом режиме будут работать в разы быстрее.

3. Надежность и валидация: XDTO — безусловный лидер. Если файл должен проходить строгую проверку (валидацию) на стороне приемника, XDTO гарантирует соответствие схеме.

4. Гибкость: Использование ЗаписатьБезОбработки() позволяет совместить лучшее из двух миров: стандартный потоковый вывод 1С и кастомные текстовые вставки в нужных местах файла.

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

← На главную