Как устроен XML-файл, который пишет и читает 1С

· 9 мин

Содержание

Структура XML в 1С зависит от того, кто формирует файл. Если файл пишет платформа через ЗаписатьXML(), корневой тег — имя объекта метаданных (DocumentObject.РеализацияТоваровУслуг), внутри — стандартные реквизиты на английском (Ref, Date, Number) и реквизиты конфигурации на русском. Если файл строится по пакету XDTO или правилам конвертации, схему задаёт XSD или формат обмена, а не конфигурация.

На практике встречаются три схемы: сериализация XDTO «как есть», сообщения планов обмена и форматы конвертации (EnterpriseData, «Конвертация данных 2.x»). Первую выбирают для переноса между одинаковыми конфигурациями, вторую — для распределённых баз, третью — когда конфигурации разные. Ниже — как выглядит каждый файл, какие типы во что превращаются и как не утонуть в гигабайтной выгрузке.

Три схемы XML-файлов в 1С и когда какая нужна

СхемаКто формируетКорневой элементКогда выбирают
Сериализация XDTOЗаписатьXML(), СериализаторXDTOимя объекта: CatalogObject.Номенклатураперенос между базами с одной конфигурацией
Сообщение обменаПланыОбмена.СоздатьЗаписьСообщения()v8msg:Message с Header и BodyРИБ и обмены по плану обмена
EnterpriseDataБСП, обработчики конвертацииMessage в пространстве .../EnterpriseData/...обмен разных конфигураций: БП, УТ, ERP
Конвертация данных 2.xправила из КД 2ФайлОбмена с атрибутом ВерсияФорматастарые обмены через универсальный формат

Схемы не смешиваются. Файл, выгруженный обработкой «Выгрузка и загрузка данных XML», не загрузится через правила EnterpriseData, и наоборот. Перед разбором чужого файла откройте его в любом текстовом редакторе и посмотрите на корневой тег и атрибут xmlns — это сразу скажет, с какой схемой вы имеете дело.

Выгрузка конфигурации в файлы (1cv8 DESIGNER ... /DumpConfigToFiles) тоже даёт XML, но это описание метаданных, а не данных. Это отдельная структура, к обмену она не относится.

Как 1С сериализует объект: ЗаписатьXML и ПрочитатьXML

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

Ключевые объекты встроенного языка:

  • 📝 ЗаписьXML — потоковая запись файла или строки;
  • 📖 ЧтениеXML — потоковое чтение, узел за узлом;
  • 🔄 ЗаписатьXML() и ПрочитатьXML() — глобальные методы, которые сериализуют объект целиком;
  • 🧩 СериализаторXDTO — то же, но с промежуточным ОбъектXDTO, если его нужно доработать перед записью.

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

&НаСервереБезКонтекста
Процедура ВыгрузитьДокумент(Ссылка, ИмяФайла)
    Запись = Новый ЗаписьXML;
    Запись.ОткрытьФайл(ИмяФайла, "UTF-8");
    Запись.ЗаписатьОбъявлениеXML();
    ЗаписатьXML(Запись, Ссылка.ПолучитьОбъект());
    Запись.Закрыть();
КонецПроцедуры

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

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

Объект = ПрочитатьXML(Чтение);
Объект.ОбменДанными.Загрузка = Истина;
Объект.Записать();

Флаг ОбменДанными.Загрузка отключает проверки и обработчики ПередЗаписью и ОбработкаПроверкиЗаполнения в типовом коде. Без него загрузка падает на первом документе, у которого пока нет контрагента или склада.

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

Пакеты XDTO: когда структуру файла задаёт схема

Сериализация «как есть» подходит, пока обе стороны — 1С с одинаковыми метаданными. Как только файл нужен внешней системе (банку, маркетплейсу, сервису поставщика), структуру диктует чужая XSD-схема. Для этого в 1С есть XDTO.

Как это устроено:

  1. 📦 XSD-схему импортируют в конфигурацию: в дереве метаданных Общие → XDTO-пакеты, команда импорта схемы. Пакет получает пространство имён из targetNamespace схемы.
  2. 🏭 Типы пакета доступны через глобальную ФабрикаXDTO. Если менять конфигурацию нельзя, фабрику строят «на лету» из файла схемы функцией СоздатьФабрикуXDTO().
  3. 🧱 По типу создают ОбъектXDTO, заполняют свойства и пишут через Фабрика.ЗаписатьXML().
Фабрика = СоздатьФабрикуXDTO("C:\schemas\order.xsd");
ТипЗаказа = Фабрика.Тип("http://example.org/order", "Order");
Заказ = Фабрика.Создать(ТипЗаказа);
Заказ.Number = "15";
Заказ.Date = ТекущаяДатаСеанса();
Заказ.Проверить(); // исключение, если объект не соответствует схеме

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

Чтение идёт тем же путём: Фабрика.ПрочитатьXML(Чтение, ТипЗаказа) возвращает ОбъектXDTO, к полям которого обращаются через точку. Имена свойств совпадают с именами элементов схемы, поэтому они обычно латиницей.

Разница с сериализацией в одной фразе: в XDTO-пакете вы сами решаете, где лежат данные из 1С. Сопоставление «поле схемы → реквизит» пишется кодом, и это главный объём работы в любой интеграции.

Разбор XML-файла документа по тегам

Так выглядит выгрузка поступления товаров через ЗаписатьXML() (сокращённо, GUID обрезаны для читаемости):

<?xml version="1.0" encoding="UTF-8"?>
<DocumentObject.ПоступлениеТоваровУслуг
    xmlns="http://v8.1c.ru/8.1/data/enterprise/current-config"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Ref>4f1b2c3d-...-0050568a1b2c</Ref>
  <DeletionMark>false</DeletionMark>
  <Date>2026-03-15T10:24:00</Date>
  <Number>0000-000042</Number>
  <Posted>true</Posted>
  <Организация>9a8b7c6d-...-0050568a1b2c</Организация>
  <Контрагент>1e2f3a4b-...-0050568a1b2c</Контрагент>
  <ВидОперации>Товары</ВидОперации>
  <СуммаДокумента>12500</СуммаДокумента>
  <Товары>
    <Row>
      <Номенклатура>5c6d7e8f-...-0050568a1b2c</Номенклатура>
      <Количество>10</Количество>
      <Цена>1250</Цена>
      <Сумма>12500</Сумма>
    </Row>
  </Товары>
</DocumentObject.ПоступлениеТоваровУслуг>

Что здесь важно:

  • 🏷️ Корневой тег = вид объекта + имя в метаданных. Для справочника — CatalogObject.Имя, для регистра сведений — InformationRegisterRecordSet.Имя.
  • 🌐 Пространство имён .../current-config означает «текущая конфигурация». Отсюда и требование: в базе-приёмнике должны быть объекты с теми же именами.
  • 🔑 Ref — GUID объекта. По нему загрузка находит существующий документ и перезаписывает его, а не создаёт дубль.
  • 🔗 Ссылочные реквизиты (Организация, Контрагент) хранят только GUID. Самих контрагентов в файле нет — их нужно выгрузить отдельно.
  • 📋 Табличная часть — элемент с её именем, каждая строка — Row.
  • 📛 Значение перечисления (ВидОперации) пишется по имени значения, а не по синониму.

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

Таблица соответствия типов данных 1С и XML

Тип в 1СКак выглядит в XMLПример значения
Строкаxs:stringООО «Ромашка»
Числоxs:decimal, разделитель — точка1250.5
Датаxs:dateTime2026-03-15T10:24:00
Пустая датаминимальная дата0001-01-01T00:00:00
Булевоxs:booleantrue / false
Ссылка на справочник или документGUID строкой5c6d7e8f-...
Пустая ссылканулевой GUID00000000-0000-0000-0000-000000000000
Перечислениеимя значенияТовары
УникальныйИдентификаторстрока UUID4f1b2c3d-...
ДвоичныеДанные, ХранилищеЗначенияxs:base64Binaryдлинная строка base64
Составной типзначение + атрибут xsi:typexsi:type="CatalogRef.Контрагенты"
Неопределенопустой элемент с xsi:nil="true"<Субконто1 xsi:nil="true"/>

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

<Субконто1 xsi:type="CatalogRef.Контрагенты">1e2f3a4b-...</Субконто1>

Для примитивов в составном типе пишется XSD-тип: xsi:type="xs:string" или xsi:type="xs:decimal".

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

ХранилищеЗначения раздувает файл сильнее всего: картинки номенклатуры и присоединённые файлы превращаются в base64, и объём растёт примерно на треть от исходного размера. Для переноса справочников без вложений такие реквизиты лучше очистить на стороне выгрузки.

Иерархия, табличные части и вложенные структуры в XML

Иерархия справочника. Вложенности тегов нет: группы и элементы лежат в файле на одном уровне. Связь задаёт реквизит Parent с GUID группы, а признак группы — IsFolder:

<CatalogObject.Номенклатура>
  <Ref>aa11...</Ref>
  <IsFolder>false</IsFolder>
  <Parent>bb22...</Parent>
  <Code>00-00000123</Code>
  <Description>Бумага А4</Description>
</CatalogObject.Номенклатура>

Порядок загрузки групп и элементов при этом не критичен. Ссылка по GUID записывается, даже если группа ещё не загружена: до её появления в базе будет «битая» ссылка, после — нормальная.

Наборы записей регистров. Регистр выгружается не записью, а набором: внутри Filter (отбор по измерению или регистратору) и Records со строками Record. При загрузке набор с тем же отбором заменяет существующие записи целиком — учитывайте это, если выгружаете регистр частями.

Универсальные коллекции. Массив, Структура, Соответствие и ТаблицаЗначений тоже сериализуются, но в другом пространстве имён — http://v8.1c.ru/8.1/data/core. Значения внутри помечаются xsi:type. Это удобно, чтобы передать параметры между базами или сохранить настройки в файл.

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

Запись.ЗаписатьНачалоЭлемента("Order");
Запись.ЗаписатьАтрибут("number", Документ.Номер);
Для Каждого Строка Из Документ.Товары Цикл
    Запись.ЗаписатьНачалоЭлемента("Item");
    Запись.ЗаписатьАтрибут("sku", Строка.Номенклатура.Артикул);
    Запись.ЗаписатьАтрибут("qty", XMLСтрока(Строка.Количество));
    Запись.ЗаписатьКонецЭлемента(); // Item
КонецЦикла;
Запись.ЗаписатьКонецЭлемента(); // Order

Функция XMLСтрока() переводит число, дату и булево в XML-представление: точка вместо запятой, без пробелов-разделителей разрядов, дата в формате ISO. Обычное Строка(Число) даст 1 250,5 — внешняя система такое не разберёт.

Проверка и оптимизация XML при обмене

Объявляйте пространства имён один раз. Если писать много объектов подряд, каждый тянет за собой xmlns:xs и xmlns:xsi. На десятках тысяч объектов это мегабайты повторов. Решение — общий корневой элемент с объявлениями:

Запись.ЗаписатьНачалоЭлемента("Data");
Запись.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");
Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
    ЗаписатьXML(Запись, Выборка.ПолучитьОбъект());
КонецЦикла;
Запись.ЗаписатьКонецЭлемента();

Читайте потоком, а не DOM. ДокументDOM грузит весь файл в память. Для файла на 2 ГБ серверу понадобится в разы больше оперативной памяти. ЧтениеXML идёт по узлам и держит в памяти один объект:

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ИмяФайла);
Чтение.ПерейтиКСодержимому(); // корневой Data
Чтение.Прочитать();           // первый объект внутри
Пока ВозможностьЧтенияXML(Чтение) Цикл
    Объект = ПрочитатьXML(Чтение);
    Объект.ОбменДанными.Загрузка = Истина;
    Объект.Записать();
КонецЦикла;
Чтение.Закрыть();

ВозможностьЧтенияXML() возвращает Ложь, когда текущий узел — не объект, который платформа умеет прочитать (например, закрывающий тег Data). Так цикл останавливается сам.

Проверяйте по схеме до отправки. Для XDTO-объектов есть Проверить(): он вызывает исключение с описанием нарушенного ограничения (пропущено обязательное поле, строка длиннее maxLength). Вызывайте его в попытке и пишите текст ошибки в журнал регистрации — так видно, какой документ и какое поле не прошли.

Кодировка — только UTF-8. Указывайте её явно в ОткрытьФайл() и в объявлении. Файл в Windows-1251 без объявления кодировки даст кракозябры в наименованиях у получателя.

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

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

Можно ли перенести данные XML-выгрузкой между БП и УТ?
Сериализацией «как есть» — нет: имена объектов и реквизитов разные. Для разных конфигураций используют формат EnterpriseData или правила конвертации.
Чем выгрузить справочник в XML без программирования?
Обработкой «Выгрузка и загрузка данных XML» с диска ИТС. Она сериализует выбранные объекты вместе со ссылками, а приёмник должен иметь ту же конфигурацию.
Почему стандартные теги на английском, а реквизиты на русском?
Стандартные реквизиты (Ref, Code, Description, Parent) общие для платформы и пишутся по внутренним именам. Реквизиты конфигурации идут по именам из метаданных, как их задал разработчик.
Изменится ли GUID объекта после загрузки?
Нет. ПрочитатьXML() создаёт объект с идентификатором из Ref, поэтому повторная загрузка того же файла обновит объекты, а не создаст дубли.
Как открыть XML от 1С, чтобы разобраться в структуре?
Подойдёт любой редактор с подсветкой XML и сворачиванием узлов. Для файлов больше 100 МБ берите редактор, который не грузит файл целиком в память.