Выгрузка данных в XML из 1С 8.3: код, схемы XSD и проверка файла

· 10 мин

Содержание

Чтобы создать XML файл в 1С 8.3, на сервере создают объект ЗаписьXML, открывают файл методом ОткрытьФайл(), по очереди пишут элементы через ЗаписатьНачалоЭлемента(), ЗаписатьАтрибут(), ЗаписатьТекст(), ЗаписатьКонецЭлемента() и закрывают запись методом Закрыть(). Если у получателя есть схема XSD, удобнее импортировать её в XDTO-пакет и заполнять объекты по схеме: платформа сама соберёт правильную структуру.

Типичная ситуация: контрагент просит «выгрузку остатков в XML по нашему шаблону», а в типовой конфигурации такой кнопки нет. Тогда пишут небольшую внешнюю обработку . Всё, что ниже, работает на платформе 8.3 в любой конфигурации: это механизмы самой платформы, а не БП или УТ.

Подготовка: какой способ создания XML выбрать

Сначала решите, нужен ли вообще код. Часть задач закрывается штатными средствами.

ЗадачаЧем делатьНужен ли программист
Перенести данные между базами с одинаковой конфигурациейобработка «Выгрузка и загрузка данных XML» с диска ИТСнет
Обмен между разными типовыми конфигурациямивстроенные обмены (формат EnterpriseData)нет, только настройка
Выгрузка в свой формат без схемыЗаписьXML вручнуюда, простой код
Формат получателя описан схемой XSDXDTO-пакет или СоздатьФабрикуXDTO()да
Сохранить объект 1С целиком, чтобы потом загрузить обратноСериализаторXDTO / ЗаписатьXML()да

Перед написанием кода соберите три вещи:

  • 📄 Образец файла или схему XSD от получателя. Без образца вы будете угадывать имена тегов.
  • 🔤 Кодировку. Почти всегда UTF-8, реже windows-1251. Уточните заранее: кодировка указывается в объявлении <?xml ... encoding="..."?> и должна совпадать с реальной.
  • 🧮 Формат чисел и дат. Получателю обычно нужно 1234.50, а не 1 234,50, и дата вида 2026-10-07, а не 07.10.2026.

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

Как создать XML файл вручную через ЗаписьXML

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

Шаг 1. Создайте внешнюю обработку

  1. В Конфигураторе: Файл → Новый… → Внешняя обработка.
  2. Добавьте форму, на форме — команду «Выгрузить».
  3. В модуле формы напишите две процедуры: серверную (формирует файл) и клиентскую (отдаёт его пользователю).

Шаг 2. Серверная часть: формирование файла

Пример выгружает справочник номенклатуры. Поле Артикул есть в БП 3.0 и УТ 11; в своей конфигурации подставьте нужные реквизиты.

&НаСервере
Функция СформироватьXMLНаСервере()

    ИмяФайла = ПолучитьИмяВременногоФайла("xml");

    Запись = Новый ЗаписьXML;
    Параметры = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина); // кодировка, версия, отступы
    Запись.ОткрытьФайл(ИмяФайла, Параметры);
    Запись.ЗаписатьОбъявлениеXML();

    Запись.ЗаписатьНачалоЭлемента("Каталог");
    Запись.ЗаписатьАтрибут("ДатаВыгрузки", XMLСтрока(ТекущаяДатаСеанса()));

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Номенклатура.Код КАК Код,
    |    Номенклатура.Наименование КАК Наименование,
    |    Номенклатура.Артикул КАК Артикул
    |ИЗ
    |    Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |    НЕ Номенклатура.ЭтоГруппа
    |    И НЕ Номенклатура.ПометкаУдаления";
    Выборка = Запрос.Выполнить().Выбрать();

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

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

        Запись.ЗаписатьНачалоЭлемента("Артикул");
        Запись.ЗаписатьТекст(СокрЛП(Выборка.Артикул));
        Запись.ЗаписатьКонецЭлемента(); // Артикул

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

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

    Данные = Новый ДвоичныеДанные(ИмяФайла);
    УдалитьФайлы(ИмяФайла);

    Возврат ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);

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

Что получится на выходе:

<?xml version="1.0" encoding="UTF-8"?>
<Каталог ДатаВыгрузки="2026-10-07T10:15:00">
	<Товар Код="00-00000012">
		<Наименование>Бумага А4, 500 л.</Наименование>
		<Артикул>SV-A4-80</Артикул>
	</Товар>
</Каталог>

Шаг 3. Клиентская часть: сохранение файла у пользователя

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

&НаКлиенте
Процедура Выгрузить(Команда)
    Адрес = СформироватьXMLНаСервере();
    ФайловаяСистемаКлиент.СохранитьФайл(Неопределено, Адрес, "katalog.xml");
КонецПроцедуры

Во внешней обработке без БСП используйте глобальный метод ПолучитьФайл() или его асинхронный аналог из синтакс-помощника.

Правила, которые экономят время

  • 🔢 Числа, даты и булевы значения — через XMLСтрока(). Она вернёт 1234.5, 2026-10-07T00:00:00 и true. Обычное Строка() даст пробелы-разделители и запятую.
  • 📅 Дата без времени — Формат(Дата, "ДФ=yyyy-MM-dd"), если получатель ждёт только дату.
  • 🏷 Имена элементов — только латиница, цифры, _, -, .; начинаться с цифры нельзя. Кириллица в именах допустима по стандарту, но многие внешние системы её не читают. Для обмена лучше латиница.
  • 🧩 Пространство имён задают сразу после открытия корневого элемента: Запись.ЗаписатьСоответствиеПространстваИмен("", "urn:example:catalog").
  • 📝 XML в строку, а не в файл: вместо ОткрытьФайл() вызовите Запись.УстановитьСтроку(), а текст заберите из Запись.Закрыть(). Удобно для отправки через HTTP-сервис.

XML по схеме XSD: XDTO-пакеты в 1С 8.3

Если получатель прислал схему XSD (налоговые форматы, маркетплейсы, банки, ГИС), вручную расставлять теги рискованно. Одна опечатка в имени, и файл не примут. Надёжнее отдать структуру платформе.

Способ 1. Импорт схемы в конфигурацию

  1. В Конфигураторе откройте дерево Общие → XDTO-пакеты.
  2. В контекстном меню группы выберите импорт XML-схемы и укажите файл XSD.
  3. Платформа создаст пакет с пространством имён из схемы. Все типы будут видны в дереве пакета.
  4. Обновите конфигурацию базы данных.

Изменение типовой конфигурации снимает её с полной поддержки. Если базу обновляют типовыми релизами, лучше способ 2: он не трогает конфигурацию.

Способ 2. Загрузка схемы из файла во время работы

Глобальная функция СоздатьФабрикуXDTO() строит фабрику прямо из файла XSD. Её можно вызвать во внешней обработке:

&НаСервере
Функция ЗаказВXML(ПутьКСхеме)

    Фабрика = СоздатьФабрикуXDTO(ПутьКСхеме);
    ПИ = "urn:example:order"; // targetNamespace из схемы

    Заказ = Фабрика.Создать(Фабрика.Тип(ПИ, "Order"));
    Заказ.Number = "125";
    Заказ.Date = '20261007';

    Строка1 = Фабрика.Создать(Фабрика.Тип(ПИ, "Item"));
    Строка1.Sku = "SV-A4-80";
    Строка1.Qty = 10;
    Заказ.Item.Добавить(Строка1); // свойство с maxOccurs > 1 — это список

    Заказ.Проверить(); // исключение, если объект не соответствует схеме

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

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

Имена типов (Order, Item) и свойств берите строго из схемы, с учётом регистра. В схеме они могут быть объявлены как complexType или как анонимный тип внутри element: во втором случае тип получают через свойство владельца, например Заказ.Свойства().Получить("Item").Тип.

Чем XDTO лучше ручной записи

КритерийЗаписьXML вручнуюXDTO по схеме
Порядок элементовследите самиберётся из схемы
Обязательные полялегко пропуститьПроверить() укажет
Типы значенийстроки, приводите самиприводятся по схеме
Скорость написаниябыстрее для 3–5 теговбыстрее для сложных форматов
Объём памятиминимальныйвесь объект в памяти

Сериализация объектов 1С

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

Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл(ИмяФайла);
СериализаторXDTO.ЗаписатьXML(Запись, ДокументСсылка.ПолучитьОбъект());
Запись.Закрыть();

Такой файл понимает только 1С с той же структурой метаданных. Внешней системе его не отдают.

Спецсимволы и экранирование при записи XML

Пять символов в XML служебные. Если записать их в текст как есть, файл не откроется.

СимволКак записываетсяГде опасен
&&amp;везде: «ООО Мир & Ко»
<&lt;текст, атрибуты
>&gt;текст (безопасно, но экранируют)
"&quot;значения атрибутов
'&apos;значения атрибутов в одинарных кавычках

Хорошая новость: ЗаписатьТекст() и ЗаписатьАтрибут() экранируют это сами. Склеивать "&amp;" вручную не нужно, иначе получится двойное &amp;amp;.

Проблемы начинаются в двух местах.

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

Управляющие символы. Коды 0–31, кроме табуляции, перевода строки и возврата каретки, в XML 1.0 запрещены вообще, экранирование их не спасает. Они попадают в базу при копировании из PDF и Excel. Найти их помогает глобальная функция НайтиНедопустимыеСимволыXML(): она возвращает позицию первого запрещённого символа или 0. Перед записью длинных текстов (комментарии, описания номенклатуры) проверяйте строку и вычищайте такие символы.

Если внутри элемента нужен кусок HTML или текст с большим количеством < и &, запишите его методом ЗаписатьСекциюCDATA(). Содержимое CDATA не разбирается парсером, но строка ]]> внутри недопустима.

Большие объёмы: потоковая выгрузка в XML

На справочнике в 200 строк любой способ работает. На выгрузке 500 000 строк движений разница становится заметной.

Что держит память и время:

  • 🐘 Запрос.Выполнить().Выгрузить() создаёт таблицу значений со всеми строками. Используйте Выбрать() и цикл Пока Выборка.Следующий(): строки читаются порциями.
  • 🐘 Обращение через точку в цикле (Выборка.Ссылка.Владелец.ИНН) делает отдельный запрос на каждую строку. Все нужные поля получайте в тексте запроса.
  • 🐘 DOM и XDTO для всего файла. ДокументDOM и объект XDTO строятся целиком в памяти. Для огромных файлов пишите корень и обёртку через ЗаписьXML, а каждую повторяющуюся запись формируйте отдельно.
  • 🐘 УстановитьСтроку() на сотни мегабайт. Строка живёт в памяти процесса, пишите сразу в файл.

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

Длинную выгрузку на клиент-серверной базе запускайте фоновым заданием или регламентом в нерабочее время. Серверный вызов из формы держит сеанс пользователя, и при обрыве связи файл останется недописанным.

Ещё два практических момента:

  1. Пишите во временный файл, а не сразу в общую папку. Получатель может забрать недописанный файл. Переименовывайте или перемещайте его только после Закрыть().
  2. Если формат допускает, режьте выгрузку на части, например по 50 000 записей. Многие внешние системы ограничивают размер одного файла.

Проверка созданного XML файла

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

Уровень 1. Корректность разметки

Самый быстрый тест: прочитать файл обратно. Если разметка битая, ЧтениеXML вызовет исключение и укажет строку.

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Попытка
    Пока Чтение.Прочитать() Цикл
    КонецЦикла;
    Сообщить("Разметка корректна");
Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;
Чтение.Закрыть();

Без кода: откройте файл в браузере. Chrome и Firefox показывают ошибку разбора с номером строки.

Уровень 2. Соответствие схеме

Если файл собран через XDTO, Проверить() уже отработал. Для файла, собранного вручную, прочитайте его фабрикой из той же схемы и проверьте объект:

Фабрика = СоздатьФабрикуXDTO(ПутьКСхеме);
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Объект = Фабрика.ПрочитатьXML(Чтение, Фабрика.Тип("urn:example:order", "Order"));
Чтение.Закрыть();
Объект.Проверить();

Вне 1С схему проверяет утилита xmllint: xmllint --noout --schema order.xsd order.xml. Она есть в большинстве дистрибутивов Linux и ставится на Windows.

Уровень 3. Содержание

Схема не поймёт, что вы выгрузили помеченные на удаление позиции или суммы без НДС вместо сумм с НДС. Сравните итоги:

Проверка XML перед отправкой
Выполнено: 0 / 7

Частые ошибки при создании XML в 1С

Диагностика: выберите симптом

Частые вопросы

Можно ли создать XML файл в 1С без программирования?
Да, если формат уже поддерживается: обмены через EnterpriseData, регламентированная отчётность, обмен с сайтом. Для произвольного формата нужна обработка.
Чем ЗаписьXML отличается от ДокументDOM?
ЗаписьXML пишет потоком и почти не расходует память. ДокументDOM хранит всё дерево и позволяет менять узлы до сохранения, но на больших файлах тяжёлый.
Где сохраняется файл, если код выполняется на сервере?
На компьютере сервера 1С, во временном каталоге его пользователя. Пользователю файл передают через временное хранилище.
Нужна ли строка объявления XML?
Для большинства получателей да: в ней указана кодировка. Без неё парсер считает файл UTF-8, и windows-1251 прочитается неверно.
Как записать пустой элемент вида `<Note/>`?
Вызовите ЗаписатьНачалоЭлемента("Note") и сразу ЗаписатьКонецЭлемента() без текста. Платформа запишет короткую форму.