При интеграции 1С с внешними системами, государственными порталами или сервисами электронного документооборота (ЭДО) разработчики часто сталкиваются с жесткими требованиями к формату XML. Стандартный объект ЗаписьXML в 1С отлично справляется с типовыми задачами, но иногда его возможностей недостаточно. Например, когда требуется вставить специфическое объявление DOCTYPE, нестандартные инструкции обработки или когда структура файла настолько сложна, что код на ЗаписьXML становится нечитаемым.
В этой статье мы подробно разберем несколько подходов к решению этой задачи: от гибкого использования текстовых шаблонов в макетах до профессиональной работы с XDTO и DOM. Мы проанализируем, как сделать код прозрачным, а процесс формирования файла — максимально надежным.
Это один из самых популярных способов среди опытных разработчиков, когда нужно быстро создать сложную "простыню" 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.НеИспользовать.
Если вам нужно использовать преимущества ЗаписьXML (автоматическое управление закрытием тегов и контроль структуры), но при этом необходимо добавить свой заголовок, рассмотрим комбинированный подход. Вы можете сначала записать в файл произвольный текст (заголовок), а затем продолжить работу через стандартный объект.
Проанализируем пример использования метода ЗаписатьБезОбработки(), который есть у объекта ЗаписьXML. Этот метод позволяет вставить строку "как есть" в поток записи.
Процедура ЗаписатьСКастомнымЗаголовком()
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Temp\custom.xml", "UTF-8");
// Вставляем свое объявление или DOCTYPE
Запись.ЗаписатьБезОбработки("<!DOCTYPE MyRoot SYSTEM ""my.dtd"">" + Символы.ПС);
// Дальше работаем стандартно
Запись.ЗаписатьНачалоЭлемента("Root");
Запись.ЗаписатьАтрибут("Версия", "1.0");
Запись.ЗаписатьНачалоЭлемента("Data");
Запись.ЗаписатьТекст("Пример данных");
Запись.ЗаписатьКонецЭлемента(); // Data
Запись.ЗаписатьКонецЭлемента(); // Root
Запись.Закрыть();
КонецПроцедуры
Этот способ позволяет избежать ручной сборки всего файла, при этом решая проблему нестандартных заголовков.
Выясним причину, по которой многие выбирают XDTO (XML Data Transfer Objects). Если у вас есть XSD-схема целевого файла, XDTO — это самый надежный вариант. Платформа сама проконтролирует типы данных, порядок следования узлов и обязательность заполнения атрибутов.
Разберем процесс по шагам:
ФабрикаXDTO.Создать() для создания структуры документа в памяти.Структурой или СправочникомОбъектом.
Процедура ЗаписатьЧерез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С и кастомные текстовые вставки в нужных местах файла.
Таким образом, выбор метода зависит от конкретных технических требований вашей задачи. Начните с анализа того, насколько часто будет меняться формат файла и насколько важна строгая валидация по схеме.