Выгрузка данных в XML из 1С 8.3: код, схемы XSD и проверка файла
Содержание
Чтобы создать XML файл
в 1С 8.3, на сервере создают объект ЗаписьXML, открывают файл методом ОткрытьФайл(), по очереди пишут элементы через ЗаписатьНачалоЭлемента(), ЗаписатьАтрибут(), ЗаписатьТекст(), ЗаписатьКонецЭлемента() и закрывают запись методом Закрыть(). Если у получателя есть схема XSD, удобнее импортировать её в XDTO-пакет и заполнять объекты по схеме: платформа сама соберёт правильную структуру.
Типичная ситуация: контрагент просит «выгрузку остатков в XML по нашему шаблону», а в типовой конфигурации такой кнопки нет. Тогда пишут небольшую внешнюю обработку . Всё, что ниже, работает на платформе 8.3 в любой конфигурации: это механизмы самой платформы, а не БП или УТ.
Подготовка: какой способ создания XML выбрать
Сначала решите, нужен ли вообще код. Часть задач закрывается штатными средствами.
| Задача | Чем делать | Нужен ли программист |
|---|---|---|
| Перенести данные между базами с одинаковой конфигурацией | обработка «Выгрузка и загрузка данных XML» с диска ИТС | нет |
| Обмен между разными типовыми конфигурациями | встроенные обмены (формат EnterpriseData) | нет, только настройка |
| Выгрузка в свой формат без схемы | ЗаписьXML вручную | да, простой код |
| Формат получателя описан схемой XSD | XDTO-пакет или СоздатьФабрику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. Создайте внешнюю обработку
- В Конфигураторе:
Файл → Новый… → Внешняя обработка. - Добавьте форму, на форме — команду «Выгрузить».
- В модуле формы напишите две процедуры: серверную (формирует файл) и клиентскую (отдаёт его пользователю).
Шаг 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. Импорт схемы в конфигурацию
- В Конфигураторе откройте дерево
Общие → XDTO-пакеты. - В контекстном меню группы выберите импорт XML-схемы и укажите файл XSD.
- Платформа создаст пакет с пространством имён из схемы. Все типы будут видны в дереве пакета.
- Обновите конфигурацию базы данных.
Изменение типовой конфигурации снимает её с полной поддержки. Если базу обновляют типовыми релизами, лучше способ 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;.
Проблемы начинаются в двух местах.
ЗаписатьБезОбработки() пишет строку как есть. Его используют, чтобы вставить готовый фрагмент 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). Память держит только одну строку, а структура остаётся проверяемой.
Длинную выгрузку на клиент-серверной базе запускайте фоновым заданием или регламентом в нерабочее время. Серверный вызов из формы держит сеанс пользователя, и при обрыве связи файл останется недописанным.
Ещё два практических момента:
- Пишите во временный файл, а не сразу в общую папку. Получатель может забрать недописанный файл. Переименовывайте или перемещайте его только после
Закрыть(). - Если формат допускает, режьте выгрузку на части, например по 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 в 1С
& или <. Ищите вызовы ЗаписатьБезОбработки() и ручную склейку строк с тегами.НайтиНедопустимыеСимволыXML() и очистите его перед записью.ПараметрыЗаписиXML и согласуйте её с получателем.Item и item — разные элементы. Сверьте с образцом и targetNamespace схемы.Закрыть() или выгрузка упала с исключением. Оберните запись в Попытка и закрывайте запись в обеих ветках.Частые вопросы
Можно ли создать XML файл в 1С без программирования?
Чем ЗаписьXML отличается от ДокументDOM?
ЗаписьXML пишет потоком и почти не расходует память. ДокументDOM хранит всё дерево и позволяет менять узлы до сохранения, но на больших файлах тяжёлый.Где сохраняется файл, если код выполняется на сервере?
Нужна ли строка объявления XML?
Как записать пустой элемент вида `<Note/>`?
ЗаписатьНачалоЭлемента("Note") и сразу ЗаписатьКонецЭлемента() без текста. Платформа запишет короткую форму.