Работа с форматом XML в 1С: чтение, запись и XDTO

· 9 мин

Содержание

Отдельной кнопки «добавить формат XML » в 1С нет. Формат подключают кодом на встроенном языке 1С:Предприятие 8.3: это потоковые объекты ЧтениеXML и ЗаписьXML, автоматическая сериализация через СериализаторXDTO или типы из готовой схемы XSD через ФабрикаXDTO.

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

Три механизма работы с XML и когда какой брать

В платформе уживаются четыре разных подхода к XML. Три основных решают почти все задачи обмена.

  • 📄 Потоковые ЧтениеXML / ЗаписьXML — читают и пишут файл узел за узлом. Полный контроль над каждым тегом и атрибутом, но весь разбор пишете вручную. Подходит для произвольного чужого формата.
  • 🔁 СериализаторXDTO — выгружает и загружает объекты конфигурации (элементы справочников, документы, записи регистров) без ручной разметки. Структуру XML платформа формирует сама.
  • 🧩 ФабрикаXDTO — создаёт объекты по типам из схемы XSD. Типы и их проверка берутся из схемы, которую вы импортировали в конфигурацию или загрузили в коде.
  • 🌳 Объектная модель DOM (ПостроительDOM, ДокументDOM) — загружает весь файл в память деревом и позволяет выбирать узлы, в том числе по XPath. Удобна, когда нужен не последовательный разбор, а доступ к произвольным ветвям.

Для большинства типовых обменов хватает первых двух: потоковое чтение для входящих файлов и XDTO-сериализация для выгрузки своих данных.

Какой механизм работы с XML выбрать?

Запись XML-файла объектом ЗаписьXML

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

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

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

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

Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Код", "000001");
Запись.ЗаписатьТекст("Карандаш чернографитный");
Запись.ЗаписатьКонецЭлемента();

Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Код", "000002");
Запись.ЗаписатьТекст("Тетрадь 48 листов");
Запись.ЗаписатьКонецЭлемента();

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

Что здесь важно по шагам:

  1. ОткрытьФайл принимает путь и кодировку. Кодировку указывайте явно — иначе принимающая система может прочитать кириллицу кракозябрами.
  2. ЗаписатьОбъявлениеXML ставит строку <?xml version="1.0" encoding="UTF-8"?>.
  3. Каждому ЗаписатьНачалоЭлемента должен соответствовать свой ЗаписатьКонецЭлемента — платформа закрывает именно текущий открытый тег.
  4. Закрыть сбрасывает буфер в файл. Без него данные могут остаться недописанными.

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

Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Пинг");
Запись.ЗаписатьТекст("ok");
Запись.ЗаписатьКонецЭлемента();
ТекстXML = Запись.Закрыть();

Чтение XML-файла объектом ЧтениеXML

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

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\tovary.xml");

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

	Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
		Если Чтение.Имя = "Товар" Тогда
			Код = Чтение.ЗначениеАтрибута("Код");
			Сообщить("Код товара: " + Код);
		КонецЕсли;

	ИначеЕсли Чтение.ТипУзла = ТипУзлаXML.Текст Тогда
		Сообщить("Наименование: " + Чтение.Значение);

	КонецЕсли;

КонецЦикла;

Чтение.Закрыть();

Разбор держится на нескольких узлах, которые встречаются чаще всего:

Значение ТипУзлаXMLЧто этоГде брать данные
НачалоЭлементаоткрывающий тег <Товар>Чтение.Имя, атрибуты
КонецЭлементазакрывающий тег </Товар>только Чтение.Имя
Тексттекст внутри элементаЧтение.Значение

Атрибуты у текущего элемента доступны сразу: ЗначениеАтрибута принимает либо имя атрибута, либо его индекс. Когда имена атрибутов заранее неизвестны, их перебирают через КоличествоАтрибутов и ПрочитатьАтрибут — последний переводит курсор на очередной атрибут, после чего работают свойства Имя и Значение:

Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
	Пока Чтение.ПрочитатьАтрибут() Цикл
		Сообщить(Чтение.Имя + " = " + Чтение.Значение);
	КонецЦикла;
КонецЕсли;

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

Читать можно и не из файла: метод УстановитьСтроку принимает готовый текст XML — удобно для ответа веб-сервиса, который пришёл строкой.

Автоматическая сериализация объектов через XDTO

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

Выгрузка элемента номенклатуры:

Ссылка = Справочники.Номенклатура.НайтиПоКоду("000001");
Объект = Ссылка.ПолучитьОбъект();

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

Загрузка обратно — симметрично, через ПрочитатьXML:

Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл("C:\Обмен\nomenklatura.xml");
Объект = СериализаторXDTO.ПрочитатьXML(Чтение);
Чтение.Закрыть();

Объект.Записать();

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

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

Для одиночного примитивного значения даже сериализатор избыточен — есть глобальные функции ЗаписатьXML(Запись, Значение) и ПрочитатьXML(Чтение, Тип). Они пишут и читают число, строку, дату, булево без создания объектов XDTO.

Отдельная частая боль — даты. В XML дата хранится в формате ISO (2026-10-07T00:00:00), а не в привычном виде. Чтобы записать и прочитать дату корректно, используйте специальные функции, которые сами переводят значение в ISO и обратно:

ТекстДаты = ЗаписатьДатуXML(ТекущаяДата(), ФорматДатыXML.Дата);
// обратно:
Дата = ПрочитатьДатуXML(ТекстДаты);

Параметр ФорматДатыXML задаёт, что писать: только дату, только время или дату со временем. Не склеивайте дату в строку вручную через Строка(Дата) — получите локальный формат вроде 07.10.2026, который принимающая система не разберёт.

Типы по схеме XSD и фабрика XDTO

Если обмен идёт по формату внешней системы, у неё обычно есть схема XSD. Схема описывает, какие элементы допустимы, их типы и порядок. 1С умеет превращать схему в набор типов XDTO и дальше работать строго по ним.

Есть два пути подключить схему.

Через конфигуратор. В дереве конфигурации есть ветка «Пакеты XDTO». В неё импортируют XSD-файл — платформа создаёт пакет с типами. После этого типы доступны в коде через глобальную ФабрикаXDTO:

ТипТовар = ФабрикаXDTO.Тип("http://partner.example/exchange", "Товар");
Объект = ФабрикаXDTO.Создать(ТипТовар);
Объект.Код = "000001";
Объект.Наименование = "Карандаш";

Первый параметр Тип — это URI пространства имён из схемы, второй — локальное имя типа. Если указать несуществующий тип или присвоить свойству недопустимое значение, фабрика сообщит об ошибке — это и есть проверка по схеме.

В коде, без импорта в конфигурацию. Когда схема приходит динамически, её читают объектом ЧтениеСхемыXML, собирают в набор и строят фабрику функцией СоздатьФабрикуXDTO:

ЧтениеСхемы = Новый ЧтениеСхемыXML;
ЧтениеСхемы.ОткрытьФайл("C:\Обмен\schema.xsd");
Схема = ЧтениеСхемы.ПрочитатьСхему();
ЧтениеСхемы.Закрыть();

НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(Схема);

Фабрика = СоздатьФабрикуXDTO(НаборСхем);

Записать объект XDTO в файл можно тем же ЗаписьXML:

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

Главная выгода схемы — валидация. Когда структура данных берётся из типов XSD, вы физически не запишете элемент, которого в схеме нет, и не присвоите строку туда, где ожидается число. Это переносит проверку корректности с этапа «файл отвергла чужая система» на этап записи у вас.

Пространства имён и атрибуты в XML

Пространство имён (namespace) — это URI, который делает имена элементов уникальными между разными форматами. В файле оно выглядит как xmlns на элементе, а имена могут идти с префиксом: <cat:Товар>.

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

URI = "http://partner.example/exchange";
Запись.ЗаписатьНачалоЭлемента("Товары", URI);
Запись.ЗаписатьСоответствиеПространстваИмен("cat", URI);

Первый вызов создаёт элемент в нужном пространстве, второй привязывает к URI короткий префикс cat, чтобы файл был компактнее и читался человеком.

При чтении префикс и URI текущего узла доступны отдельными свойствами:

  • Чтение.ЛокальноеИмя — имя без префикса (Товар);
  • Чтение.Префикс — префикс, если он есть (cat);
  • Чтение.URIПространстваИмен — полный URI пространства.

Сравнивать узлы надёжнее по паре «локальное имя + URI», а не по полному имени с префиксом. Префикс в чужом файле может оказаться любым — важен именно URI, он у формата фиксированный.

Атрибуты тоже могут принадлежать пространству имён. При записи для этого есть перегрузка ЗаписатьАтрибут с указанием URI; при чтении у атрибута так же доступны ЛокальноеИмя и URIПространстваИмен. На практике большинство атрибутов пишут без пространства — тогда достаточно пары «имя, значение».

Частые ошибки при работе с XML

Разберём то, что встречается чаще всего и с чем код падает не сразу.

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

Отдельно про память: потоковые ЧтениеXML и ЗаписьXML работают с файлом любого размера, потому что держат в памяти только текущий узел. А вот загрузка всего файла в DOM или в одну строку через УстановитьСтроку на больших выгрузках (сотни мегабайт) может упереться в память рабочего процесса — для таких объёмов оставайтесь на потоковом разборе.

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

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