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

· 9 мин

Содержание

Записать XML из 1С 8.3 можно тремя способами: поэлементно через объект ЗаписьXML, собрать результат в строку (тот же объект, но без файла) или выгрузить объект целиком через XDTOСериализатор. Первый способ даёт полный контроль над структурой, второй удобен, когда XML нужно передать дальше в коде, третий пишет готовый файл в две строки.

Выбор зависит от задачи. Нужна выгрузка в чужой формат с жёсткой схемой — берите ручную запись. Нужно сохранить справочник или документ, чтобы потом прочитать обратно в 1С, — берите сериализатор. Ниже разберём все три с рабочим кодом, покажем, как добавлять пространства имён и атрибуты, и что делать с ошибками и памятью на больших выгрузках.

Три способа и когда какой выбрать

Все способы работают в любой конфигурации на платформе 8.3 — это механизм самой платформы, а не прикладного решения. Код пишут в обработке, модуле объекта или внешней обработке.

Перед выгрузкой подготовьте две вещи. Первое — решите, где выполняется код. Запись на диск сервера идёт в серверной процедуре, запись в файл на компьютере пользователя — в клиентской (либо через ПоместитьФайл). Второе — определите источник данных: запрос, выборка по справочнику или готовый объект. От объёма источника зависит выбор способа, память и место, куда писать результат.

СпособЧто делаетКогда выбирают
Объект ЗаписьXML в файлПишете каждый элемент и атрибут вручнуюВыгрузка в сторонний формат с заданной схемой XSD
ЗаписьXML в строкуТо же, но результат возвращается строкойXML нужен в коде: отправить по HTTP, положить в реквизит
XDTOСериализаторСам раскладывает объект 1С в XMLВыгрузка-загрузка между базами 1С, бэкап объекта

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

Какой способ записи XML выбрать под вашу задачу?

Ручная запись через объект ЗаписьXML

Базовый сценарий — сформировать файл поэлементно. Порядок всегда один: открыли файл, записали объявление, открывали и закрывали элементы, в конце закрыли объект.

  1. Создайте объект: Запись = Новый ЗаписьXML;
  2. Откройте файл с кодировкой: Запись.ОткрытьФайл("C:\Обмен\tovary.xml", "UTF-8");
  3. Запишите объявление <?xml version="1.0"?> методом ЗаписатьОбъявлениеXML().
  4. Открывайте элементы ЗаписатьНачалоЭлемента, пишите атрибуты и текст, закрывайте ЗаписатьКонецЭлемента.
  5. Закройте объект методом Закрыть() — только после этого файл будет дописан на диск.

Пример выгрузки номенклатуры с кодом в атрибуте и наименованием в тексте элемента:

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Обмен\tovary.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();

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

Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    Запись.ЗаписатьНачалоЭлемента("Товар");
    Запись.ЗаписатьАтрибут("Код", Выборка.Код);
    Запись.ЗаписатьТекст(Выборка.Наименование);
    Запись.ЗаписатьКонецЭлемента(); // Товар
КонецЦикла;

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

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

Каждому ЗаписатьНачалоЭлемента обязан соответствовать свой ЗаписатьКонецЭлемента. Если забыть закрыть элемент, файл получится невалидным, а ошибка всплывёт только при чтении. Комментируйте закрытие именем элемента — это экономит часы на отладке вложенных структур.

Значения перед записью приводите к строке осознанно. Число ЗаписатьТекст примет и само, но дату и булево лучше форматировать явно через Формат() или функцию XMLСтрока(), которая возвращает каноническое XML-представление значения (дата в виде 2026-10-07T00:00:00 и так далее).

Запись XML в строку без файла

Когда файл на диске не нужен — XML уходит в веб-сервис, кладётся в строковый реквизит или передаётся в фоновое задание, — инициализируйте объект методом УстановитьСтроку вместо ОткрытьФайл. Результат вернёт Закрыть().

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

Запись.ЗаписатьНачалоЭлемента("Заказ");
Запись.ЗаписатьАтрибут("Номер", "0000-0012");
Запись.ЗаписатьТекст("Поставка материалов");
Запись.ЗаписатьКонецЭлемента();

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

После этого СтрокаXML содержит весь документ как текст. Дальше его можно отправить HTTPЗапрос, сохранить в реквизит типа «Строка (неограниченная)» или положить во временное хранилище.

Тот же код работает и на клиенте, и на сервере — объект ЗаписьXML доступен в обоих контекстах. Для больших выгрузок переносите формирование на сервер: клиентская память ограничена.

Если XML нужно не записать, а, наоборот, прочитать, используется парный объект ЧтениеXML и метод ПрочитатьXML сериализатора. Логика зеркальная: открываете поток, перебираете узлы, собираете значения. Держать оба механизма под рукой полезно: выгрузку почти всегда сопровождает загрузка на приёмнике, и писать их симметрично проще, чем разбираться в чужом формате.

Отдельно про типы. Строку метод ЗаписатьТекст примет как есть. Число запишется в технической форме без разделителей разрядов. Дату форматируйте через XMLСтрока(ДатаДокумента) — вернётся каноническое представление 2026-10-07T00:00:00, которое поймёт любой XML-парсер. Булево превратите в строки true/false, если того требует схема приёмника, а не в русское «Истина/Ложь».

Автоматическая выгрузка объектов через XDTO-сериализатор

Сериализатор снимает с вас ручную работу: он сам обходит реквизиты объекта, определяет их типы и пишет корректный XML. Глобальный объект XDTOСериализатор доступен без создания.

Выгрузка одного объекта в файл:

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Обмен\kontragent.xml", "UTF-8");

Контрагент = Справочники.Контрагенты.НайтиПоКоду("00-0001");
XDTOСериализатор.ЗаписатьXML(Запись, Контрагент.ПолучитьОбъект());

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

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

Данные = Новый Структура;
Данные.Вставить("Организация", "ООО «Ромашка»");
Данные.Вставить("Дата", ТекущаяДата());

Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
XDTOСериализатор.ЗаписатьXML(Запись, Данные);
СтрокаXML = Запись.Закрыть();

Обратная операция на стороне приёмника — XDTOСериализатор.ПрочитатьXML(Чтение) — вернёт исходное значение того же типа. Поэтому сериализатор выбирают для обмена между базами 1С: формат на обеих сторонах согласован автоматически.

Сериализатор пишет XML в собственном формате 1С со служебными пространствами имён. Для выгрузки в стороннюю систему с заранее заданной схемой он не подойдёт — там нужна ручная запись.

Ещё одна пара методов для коротких задач — глобальные функции XMLСтрока(Значение) и XMLЗначение(Тип, Строка). Они переводят отдельное значение в строку и обратно без создания потока, но работают только с примитивными типами и ссылками, не с целыми объектами.

Пространства имён, атрибуты и вложенные элементы

Если принимающая система требует пространства имён (namespace) — а так работают почти все отраслевые форматы, — объявите соответствие префикса и URI до записи корневого элемента.

Запись.ЗаписатьСоответствиеПространстваИмен("ns", "http://example.org/exchange");
Запись.ЗаписатьНачалоЭлемента("Документ", "http://example.org/exchange", "ns");

Первый параметр ЗаписатьНачалоЭлемента — локальное имя элемента, второй — URI пространства имён, третий — префикс. В файле это даст <ns:Документ xmlns:ns="http://example.org/exchange">.

Атрибуты пишутся только сразу после открытия элемента, до его текста и дочерних элементов:

Запись.ЗаписатьНачалоЭлемента("Строка");
Запись.ЗаписатьАтрибут("Номер", "1");
Запись.ЗаписатьАтрибут("Сумма", XMLСтрока(1500.50));
Запись.ЗаписатьТекст("Услуги доставки");
Запись.ЗаписатьКонецЭлемента();

Порядок важен: если попытаться записать атрибут после текста или после открытия вложенного элемента, платформа выдаст ошибку. Поэтому структуру продумывают заранее — что идёт атрибутом, а что отдельным элементом.

Для вложенности просто открывайте новый элемент, не закрывая родительский:

Запись.ЗаписатьНачалоЭлемента("Заказ");
    Запись.ЗаписатьНачалоЭлемента("Клиент");
    Запись.ЗаписатьТекст("ООО «Ромашка»");
    Запись.ЗаписатьКонецЭлемента(); // Клиент

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

Отступы в коде (как выше) на сам XML не влияют — они для читаемости исходника. Форматирование готового файла с переносами строк платформа делает по умолчанию; специально управлять им через ПараметрыЗаписиXML нужно редко.

Если приёмник чувствителен к отсутствию объявления пространств имён у корня, объявляйте все соответствия префиксов до ЗаписатьНачалоЭлемента корневого элемента — тогда они попадут в атрибуты xmlns именно корня, а не разбредутся по вложенным тегам. Это частая причина того, почему валидатор на стороне партнёра отвергает в общем-то правильный файл.

Обработка ошибок и производительность больших выгрузок

Запись в файл — операция с внешним ресурсом: нет прав на папку, диск заполнен, файл занят другим процессом. Оборачивайте работу в Попытка и гарантируйте закрытие объекта.

Запись = Новый ЗаписьXML;
Попытка
    Запись.ОткрытьФайл("C:\Обмен\tovary.xml", "UTF-8");
    Запись.ЗаписатьОбъявлениеXML();
    Запись.ЗаписатьНачалоЭлемента("Номенклатура");
    // ... запись данных ...
    Запись.ЗаписатьКонецЭлемента();
Исключение
    ЗаписьЖурналаРегистрации("Выгрузка XML", УровеньЖурналаРегистрации.Ошибка,,,
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    ВызватьИсключение;
Конецпопытки;

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

Проверьте, что Закрыть() вызывается в любом случае — иначе файл останется недописанным, а дескриптор повиснет до сборки мусора. Если прервать выгрузку исключением без закрытия, на диске окажется обрезанный XML, который приёмник не прочитает.

Теперь память. Разница между способами видна именно на объёме:

  • 📁 Запись сразу в файл — поток пишется на диск по мере формирования, в памяти держится только текущий элемент. Это основной способ для выгрузок на сотни тысяч строк.
  • 🧵 Запись в строку через УстановитьСтроку — весь документ копится в оперативной памяти. Для крупной выгрузки это риск исчерпать память рабочего процесса.
  • ⚙️ XDTO-сериализатор удобен, но на объект тратит больше, чем ручная запись: он строит промежуточное XDTO-представление. На единичных объектах это незаметно, на массовой выгрузке — заметно.

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

  1. Данные берите курсором Выбрать(), а не выгружайте всё в таблицу значений разом — так в памяти не окажется весь справочник.
  2. Пишите в файл, а не в строку. Если результат всё же нужен строкой, рассмотрите выгрузку во временный файл и чтение его обратно.
  3. Тяжёлую выгрузку выносите в фоновое задание на сервере, чтобы не держать сеанс пользователя.
  4. Кодировку задавайте явно (UTF-8) и согласуйте с приёмником — рассинхрон кодировки даёт «кракозябры» в кириллице.

Путь к файлу на серверной стороне — это путь на сервере 1С, а не на компьютере пользователя. Указывайте каталог, к которому у службы сервера есть права на запись, иначе получите ошибку доступа.

Как проверить, что XML сформирован правильно

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

  • 🌐 Откройте файл в браузере. Браузер показывает XML деревом и подсвечивает место, где нарушена структура: непарный тег, недопустимый символ, сбитая кодировка. Если дерево раскрылось целиком — разметка валидна.
  • 🔁 Прочитайте файл обратно в 1С. Соберите значение методом XDTOСериализатор.ПрочитатьXML(Чтение) или переберите узлы через ЧтениеXML. Если чтение прошло без исключения, файл корректен хотя бы для самой 1С.
  • 🔤 Сверьте кодировку. Откройте файл в текстовом редакторе и убедитесь, что кириллица читается. Объявленная в заголовке кодировка должна совпадать с фактической — платформа проставит её при ЗаписатьОбъявлениеXML().

Если партнёр прислал XSD-схему и требует строгого ей соответствия, её можно загрузить в ФабрикаXDTO и писать-читать уже по типам этой схемы. Это строже ручной записи: фабрика сама проверит, что состав и типы элементов соответствуют описанию, и не даст записать лишнее.

Самую частую ошибку — непарные теги — ловит именно открытие в браузере. Делайте это до того, как отдали файл во внешнюю систему: там диагностика обычно скуднее и сводится к сухому «файл не прошёл валидацию».

Чем отличается ЗаписьXML от XDTOСериализатора?
ЗаписьXML — низкоуровневый поток: вы сами пишете каждый элемент и полностью контролируете структуру. XDTOСериализатор надстроен над ним и сам раскладывает объект 1С в XML по его типам. Сериализатор всё равно пишет через ЗаписьXML, который вы ему передаёте.
Как записать XML сразу в строку, а не в файл?
Вместо ОткрытьФайл вызовите у объекта ЗаписьXML метод УстановитьСтроку(). Сформируйте документ как обычно, а строку заберите из результата Закрыть().
Почему в выгруженном файле кириллица отображается некорректно?
Расходятся кодировки. Задавайте UTF-8 в ОткрытьФайл и убедитесь, что приёмник читает файл в той же кодировке. Объявление XML с кодировкой платформа пропишет сама при ЗаписатьОбъявлениеXML().
Можно ли выгрузить документ со всеми табличными частями одним вызовом?
Да, через XDTOСериализатор.ЗаписатьXML, передав объект документа (.ПолучитьОбъект()). Он выгрузит шапку и все табличные части. На приёмнике ПрочитатьXML соберёт документ целиком.
Как добавить к элементу атрибут?
Методом ЗаписатьАтрибут(Имя, Значение) сразу после ЗаписатьНачалоЭлемента, до текста и вложенных элементов. Если записать атрибут позже, платформа выдаст ошибку порядка записи.