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

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

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

1. Основные способы создания XML в 1С: сравнение методов

Платформа 1С:Предприятие 8.3 предлагает несколько инструментов для работы с XML. Их выбор зависит от сложности задачи, требований к производительности и удобству поддержки кода. Давайте сравним основные подходы:

  • 📝 Ручное формирование строки — простейший метод, подходящий для небольших файлов с простой структурой. Используется, когда нужно быстро сгенерировать XML без дополнительных библиотек.
  • 🔧 Объект ЗаписьXML — встроенный инструмент платформы, оптимальный для большинства задач. Поддерживает пространства имен, атрибуты и автоматически экранирует специальные символы.
  • 📊 Объект ЧтениеXML/ЗаписьXML с XDTO — расширенный вариант для работы со схемами XSD. Идеален для интеграции с системами, требующими строгой валидации структуры.
  • 🔄 Сериализация объектов — автоматическое преобразование данных 1С в XML. Удобно для типовых обменов, но требует предварительной настройки соответствий.
  • 📎 Внешние компоненты — используются для специфических форматов (например, OpenXML или Office Open XML). Актуальны, когда стандартные средства 1С не покрывают требования.

Для 80% задач достаточно первых двух методов. Объект ЗаписьXML мы рассмотрим особенно подробно, так как он сочетает гибкость, производительность и удобство. А вот ручное формирование строки стоит использовать только для тестовых целей или простейших случаев — из-за риска ошибок при экранировании символов и формировании структуры.

📊 Какой метод создания XML вы используете чаще?
Ручное формирование строк
Объект ЗаписьXML
XDTO-пакеты
Сериализация объектов
Другой
Метод Сложность реализации Производительность Поддержка пространств имен Когда использовать
Ручное формирование Низкая Средняя Нет Простые файлы, тестирование
ЗаписьXML Средняя Высокая Да Большинство задач обмена
XDTO Высокая Средняя Да Строгая валидация по XSD
Сериализация Средняя Высокая Ограниченно Типовые обмены с настройкой
⚠️ Внимание: При выборе метода учитывайте требования системы-получателя XML. Некоторые государственные сервисы (например, ФНС для отчетности) требуют строгого соблюдения схемы XSD и пространств имен. В таких случаях ручное формирование или простая запись XML могут не подойти — потребуется использовать XDTO-пакеты или внешние компоненты.

2. Ручное формирование XML: когда это оправдано

Несмотря на ограничения, ручное создание XML-строки остается актуальным в нескольких сценариях:

  • 🧪 Тестирование интеграций — когда нужно быстро сгенерировать тестовый файл для проверки обработки на стороне получателя.
  • 📄 Простые форматы — если структура XML содержит только текстовые узлы без вложенных элементов и атрибутов.
  • 🔧 Отладка — для вывода промежуточных данных в лог или сообщение пользователю.
  • 📊 Динамические запросы — когда структура XML формируется на основе пользовательского ввода и не может быть заранее описана.

Основной недостаток метода — необходимость вручную экранировать специальные символы (&, <, >, ", '). Для этого в 1С есть функция СтрЗаменить(), но ее нужно применять ко всем текстовым значениям. Пример базового кода:

Функция СформироватьXMLРучной() Экспорт

Результат = "

|<Каталог>

| <Товар>

| <Наименование>" + СтрЗаменить(Наименование, """", """) + "

| <Цена>" + Формат(Цена, "ЧГ=0") + "

|

|";

Возврат Результат;

КонецФункции

Для удобства можно создать универсальную функцию экранирования:

Функция ЭкранироватьXML(Значение) Экспорт

Значение = СтрЗаменить(Значение, "&", "&");

Значение = СтрЗаменить(Значение, "<", "<");

Значение = СтрЗаменить(Значение, ">", ">");

Значение = СтрЗаменить(Значение, """", """);

Значение = СтрЗаменить(Значение, "'", "'");

Возврат Значение;

КонецФункции

💡

Для многократного использования ручного формирования создайте общую функцию ЭкранироватьXML() в общем модуле. Это сократит код и уменьшит риск ошибок при экранировании.

⚠️ Внимание: При ручном формировании легко допустить ошибку в структуре XML (например, забыть закрывающий тег или неправильно вложить элементы). Всегда проверяйте результат через валидаторы вроде XML Validator или встроенные средства (ПрочитатьXML()).

3. Объект ЗаписьXML: универсальное решение

Объект ЗаписьXML — это основной инструмент для программного создания XML в . Он автоматически обрабатывает специальные символы, поддерживает пространства имен и позволяет гибко управлять структурой документа. Рассмотрим базовый синтаксис и ключевые методы:

Процедура СоздатьXMLФайл()

// Создаем объект записи

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

// Начинаем документ

ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("Каталог");

// Добавляем элемент с атрибутом

ЗаписьXML.ЗаписатьАтрибут("Версия", "1.0");

ЗаписьXML.ЗаписатьАтрибут("ДатаФормирования", ТекущаяДата());

// Добавляем вложенный элемент с текстом

ЗаписьXML.ЗаписатьНачалоЭлемента("Товар");

ЗаписьXML.ЗаписатьТекст("Ноутбук GameMaster 2000");

ЗаписьXML.ЗаписатьКонецЭлемента(); // Закрываем Товар

// Закрываем корневой элемент

ЗаписьXML.ЗаписатьКонецЭлемента(); // Закрываем Каталог

// Получаем результат

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

ЗаписьXML.Закрыть();

// Сохраняем в файл

Результат.Записать("C:\Temp\Каталог.xml");

КонецПроцедуры

Ключевые особенности работы с ЗаписьXML:

  • 🔹 Автоматическое экранирование — не нужно вручную обрабатывать специальные символы.
  • 🔹 Поддержка пространств имен — методы ЗаписатьПространствоИмен() и ЗаписатьАтрибутПространстваИмен().
  • 🔹 Управление форматированием — можно включать/отключать переносы строк и отступы через УстановитьСтроку().
  • 🔹 Работа с большими файлами — поддерживается запись непосредственно в файл без промежуточного хранения в памяти.

Для сложных структур удобно использовать вспомогательные процедуры:

Процедура ЗаписатьТовар(ЗаписьXML, ДанныеТовара)

ЗаписьXML.ЗаписатьНачалоЭлемента("Товар");

ЗаписьXML.ЗаписатьАтрибут("Артикул", ДанныеТовара.Артикул);

ЗаписьXML.ЗаписатьНачалоЭлемента("Наименование");

ЗаписьXML.ЗаписатьТекст(ДанныеТовара.Наименование);

ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьЭлемент("Цена", Формат(ДанныеТовара.Цена, "ЧГ=0"));

ЗаписьXML.ЗаписатьЭлемент("Количество", ДанныеТовара.Количество);

ЗаписьXML.ЗаписатьКонецЭлемента(); // Товар

КонецПроцедуры

☑️ Проверка перед сохранением XML

Выполнено: 0 / 5

4. Работа с пространствами имен и сложными структурами

Многие форматы обмена (например, УПД, Торг-12 или файлы для ЕГАИС) требуют использования пространств имен (namespaces). Объект ЗаписьXML поддерживает их через специальные методы. Рассмотрим пример с пространством имен для формата UniversalBusinessLanguage (UBL):

Процедура СоздатьUBLИнвойс()

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

// Объявляем пространства имен

ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("Invoice");

ЗаписьXML.ЗаписатьПространствоИмен("cbc", "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2");

ЗаписьXML.ЗаписатьПространствоИмен("cac", "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2");

// Добавляем элемент с префиксом пространства имен

ЗаписьXML.ЗаписатьНачалоЭлемента("cbc:ID");

ЗаписьXML.ЗаписатьТекст("INV-2023-00123");

ЗаписьXML.ЗаписатьКонецЭлемента();

// Добавляем элемент с атрибутом из другого пространства

ЗаписьXML.ЗаписатьНачалоЭлемента("cbc:IssueDate");

ЗаписьXML.ЗаписатьАтрибут("format", "YYYYMMDD", "http://www.w3.org/2001/XMLSchema-instance");

ЗаписьXML.ЗаписатьТекст(Формат(ТекущаяДата(), "ДЛФ=Д"));

ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьКонецЭлемента(); // Invoice

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

Результат.Записать("C:\Temp\Invoice.xml");

КонецПроцедуры

При работе со сложными структурами полезно:

  1. 📌 Создавать отдельные процедуры для записей повторяющихся элементов (например, строк документа или адресов).
  2. 📌 Использовать шаблоны — если структура XML стандартная (например, для 54-ФЗ), можно вынести ее описание в отдельный модуль.
  3. 📌 Валидировать результат — перед отправкой проверяйте файл через ПрочитатьXML() или внешние сервисы вроде XMLLint.

Важно: При работе с пространствами имен префиксы (например, cbc:) должны быть объявлены ДО их первого использования в документе. В противном случае XML будет невалидным.

Что будет если не объявить пространство имен?

Если пространство имен используется в XML, но не объявлено через ЗаписатьПространствоИмен(), файл станет невалидным. Большинство парсеров (включая встроенный в 1С) не смогут его корректно обработать, что приведет к ошибкам при загрузке в внешние системы.

5. Оптимизация для больших объемов данных

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

  • 🐢 Замедления работы из-за большого объема данных в памяти.
  • 💥 Ошибок нехватки памяти (особенно актуально для 1С:Предприятие в файловом варианте).
  • Длительного ожидания пользователем завершения операции.

Основные приемы оптимизации:

Проблема Решение Пример кода
Большой объем данных в памяти Запись непосредственно в файл ЗаписьXML.УстановитьФайл("C:\Temp\big.xml")
Длительное формирование Вывод прогресса пользователю Сообщить("Обработано " + Строка(Счетчик) + " из " + Всего);
Повторяющаяся структура Вынесение в отдельные процедуры ЗаписатьСтрокуДокумента(ЗаписьXML, ДанныеСтроки)
Частые обращения к базе Выборка данных пакетами Выборка.УстановитьПакетныйРежим(100)

Пример оптимизированного кода для выгрузки большого каталога:

Процедура ВыгрузитьБольшойКаталог()

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьФайл("C:\Temp\Каталог_Polnyi.xml", Ложь, "UTF-8");

ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("Каталог");

Выборка = Товары.Выбрать();

Выборка.УстановитьПакетныйРежим(50); // Обрабатываем по 50 записей

Счетчик = 0;

Пока Выборка.Следующий() Цикл

ЗаписатьТовар(ЗаписьXML, Выборка);

Счетчик = Счетчик + 1;

// Выводим прогресс каждые 100 записей

Если Счетчик % 100 = 0 Тогда

Сообщить("Обработано товаров: " + Счетчик);

КонецЕсли;

КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента(); // Каталог

ЗаписьXML.Закрыть();

Сообщить("Выгрузка завершена. Всего товаров: " + Счетчик);

КонецПроцедуры

⚠️ Внимание: При записи непосредственно в файл (УстановитьФайл()) следите за правами доступа к папке. В корпоративных сетях часто бывают ограничения на запись в системные директории (например, C:\). Используйте сетевые пути или папку %TEMP%.

6. Типичные ошибки и их решение

Даже опытные разработчики сталкиваются с ошибками при генерации XML. Рассмотрим наиболее распространенные проблемы и способы их устранения:

  • 🚫 "Недопустимый символ в значении" — возникает, когда не экранированы специальные символы (&, < и др.). Решение: использовать ЗаписьXML или функцию ЭкранироватьXML().
  • 🚫 "Не закрыт тег" — опечатка в имени элемента или пропущен ЗаписатьКонецЭлемента(). Решение: проверять баланс тегов через валидатор.
  • 🚫 "Неверное пространство имен" — префикс использован без объявления. Решение: объявить пространство через ЗаписатьПространствоИмен().
  • 🚫 "Некорректная кодировка" — символы кириллицы отображаются кракозябрами. Решение: явно указывать кодировку UTF-8 при сохранении.
  • 🚫 "Слишком большой файл" — превышен лимит памяти. Решение: записывать непосредственно в файл пакетами.

Для диагностики проблем используйте:

Процедура ПроверитьXML(ПутьКФайлу)

Попытка

ЧтениеXML = Новый ЧтениеXML;

ЧтениеXML.ОткрытьФайл(ПутьКФайлу);

Пока ЧтениеXML.Прочитать() Цикл

// Просто читаем файл для проверки валидности

КонецЦикла;

Сообщить("XML валиден!");

Исключение

Сообщить("Ошибка в XML: " + ОписаниеОшибки());

КонецПопытки;

КонецПроцедуры

Если XML предназначен для государственных систем (например, ФНС или ФСС), обязательно проверяйте его через официальные валидаторы этих служб. Требования к формату могут меняться, и то, что работало год назад, сегодня может быть отклонено.

💡

Всегда тестируйте сгенерированный XML на валидность перед отправкой в внешние системы. Даже небольшая ошибка в структуре может привести к отказу в обработке документа.

7. Практический пример: генерация XML для заказа покупателя

Рассмотрим полный пример создания XML-файла для заказа покупателя со всеми необходимыми элементами: заголовком документа, строками товаров и реквизитами контрагента. Такой формат часто используется для обмена с интернет-магазинами или системами EDI.

Процедура СоздатьXMLЗаказ(Заказ)

ЗаписьXML = Новый ЗаписьXML;

ЗаписьXML.УстановитьСтроку();

// Заголовок XML

ЗаписьXML.ЗаписатьОбъявлениеXML();

ЗаписьXML.ЗаписатьНачалоЭлемента("ЗаказПокупателя");

ЗаписьXML.ЗаписатьАтрибут("Номер", Заказ.Номер);

ЗаписьXML.ЗаписатьАтрибут("Дата", Формат(Заказ.Дата, "ДЛФ=Д"));

// Реквизиты контрагента

ЗаписьXML.ЗаписатьНачалоЭлемента("Контрагент");

ЗаписьXML.ЗаписатьЭлемент("Наименование", Заказ.Контрагент.Наименование);

ЗаписьXML.ЗаписатьЭлемент("ИНН", Заказ.Контрагент.ИНН);

ЗаписьXML.ЗаписатьЭлемент("Адрес", Заказ.Контрагент.Адрес);

ЗаписьXML.ЗаписатьКонецЭлемента(); // Контрагент

// Строки заказа

ЗаписьXML.ЗаписатьНачалоЭлемента("Строки");

Для Каждого Строка Из Заказ.Строки Цикл

ЗаписьXML.ЗаписатьНачалоЭлемента("Строка");

ЗаписьXML.ЗаписатьАтрибут("НомерСтроки", Строка.НомерСтроки);

ЗаписьXML.ЗаписатьЭлемент("Товар", Строка.Номенклатура.Наименование);

ЗаписьXML.ЗаписатьЭлемент("Количество", Строка.Количество);

ЗаписьXML.ЗаписатьЭлемент("Цена", Строка.Цена);

ЗаписьXML.ЗаписатьЭлемент("Сумма", Строка.Сумма);

ЗаписьXML.ЗаписатьКонецЭлемента(); // Строка

КонецЦикла;

ЗаписьXML.ЗаписатьКонецЭлемента(); // Строки

// Итоги

ЗаписьXML.ЗаписатьЭлемент("ИтогоСумма", Заказ.ИтогоСумма);

ЗаписьXML.ЗаписатьЭлемент("Комментарий", Заказ.Комментарий);

ЗаписьXML.ЗаписатьКонецЭлемента(); // ЗаказПокупателя

// Сохранение результата

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

Результат.Записать("C:\Temp\Заказ_" + Заказ.Номер + ".xml");

Возврат Результат.ПолучитьТекст();

КонецПроцедуры

Этот пример демонстрирует:

  • 📌 Использование атрибутов для служебной информации (номер, дата).
  • 📌 Вложенную структуру с повторяющимися элементами (строки заказа).
  • 📌 Форматирование числовых значений.
  • 📌 Сохранение файла с осмысленным именем.

Для реальных задач такой шаблон можно расширить добавлением:

  • 🔹 Пространств имен (если требуется формат обмена).
  • 🔹 Дополнительных реквизитов (например, Склад, Менеджер).
  • 🔹 Подписи или хэш-сумм для защиты от изменений.

FAQ: Частые вопросы по программному созданию XML в 1С

Как добавить комментарий в XML?

Для добавления комментариев используйте метод ЗаписатьКомментарий():

ЗаписьXML.ЗаписатьКомментарий("Этот заказ сформирован автоматически");

Комментарии полезны для документации, но не должны содержать критичную информацию — некоторые парсеры их игнорируют.

Можно ли создать XML без объекта ЗаписьXML?

Да, можно формировать строку вручную (см. раздел 2), но это чревато ошибками. Альтернатива — использовать XDTO-пакеты или СериализациюXDTO, если нужна работа со схемами XSD.

Пример с XDTO:

ФабрикаXDTO = Новый ФабрикаXDTO;

ТипЗаказа = ФабрикаXDTO.Тип("http://example.com/ns", "Заказ");

ЗаказXDTO = ФабрикаXDTO.Sоздать(ТипЗаказа);

// Заполнение свойств...

ЗаписьXML = Новый ЗаписьXML;

СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ЗаказXDTO);

Как обработать специальные символы в значениях?

Объект ЗаписьXML автоматически экранирует символы. При ручном формировании используйте функцию:

Функция ЭкранироватьXML(Текст)

Возврат СтрЗаменить(Текст, "&", "&")

+ СтрЗаменить(..., "<", "<")

+ ...; // и так для всех специальных символов

КонецФункции

Не забывайте про символы " и ', если они используются в атрибутах.

Как сжать большой XML-файл перед отправкой?

Используйте встроенные средства 1С для архивации:

ЗипФайл = Новый ЗаписьZipФайла("C:\Temp\Архив.zip");

ЗипФайл.ДобавитьФайл("C:\Temp\БольшойФайл.xml", "data.xml");

ЗипФайл.Закрыть();

Для передачи по HTTP можно сжимать данные на лету с помощью GZip:

СжатыеДанные = СжатьДанные(НесжатыеДанные, 9);
Как проверить XML на соответствие XSD-схеме?

В 1С для этого используются XDTO-пакеты:

Валидатор = Новый ВалидаторXDTO;

РезультатВалидации = Валидатор.Валидировать(ПрочитатьXML, ПутьКXSD);

Если Не РезультатВалидации.Успех Тогда

Сообщить("Ошибки: " + РезультатВалидации.Ошибки);

КонецЕсли;

Для внешней валидации можно использовать сервисы вроде XML Validation от W3C.