Работа с форматом XML в 1С: чтение, запись и XDTO
Содержание
Отдельной кнопки «добавить формат 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 — полный контроль над каждым тегом и атрибутом.СериализаторXDTO — одна строка кода на объект, формат определяет платформа.ФабрикаXDTO.Создать — типы и проверка берутся из схемы.ЗаписатьXML и ПрочитатьXML — без создания лишних объектов.ПостроительDOM с выборкой по XPath.Запись XML-файла объектом ЗаписьXML
ЗаписьXML пишет файл последовательно: вы открываете поток, по очереди добавляете объявление, начала и концы элементов, атрибуты и текст, затем закрываете файл.
Минимальный пример — выгрузка списка товаров:
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Обмен\tovary.xml", "UTF-8");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Товары");
Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Код", "000001");
Запись.ЗаписатьТекст("Карандаш чернографитный");
Запись.ЗаписатьКонецЭлемента();
Запись.ЗаписатьНачалоЭлемента("Товар");
Запись.ЗаписатьАтрибут("Код", "000002");
Запись.ЗаписатьТекст("Тетрадь 48 листов");
Запись.ЗаписатьКонецЭлемента();
Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();
Что здесь важно по шагам:
ОткрытьФайлпринимает путь и кодировку. Кодировку указывайте явно — иначе принимающая система может прочитать кириллицу кракозябрами.ЗаписатьОбъявлениеXMLставит строку<?xml version="1.0" encoding="UTF-8"?>.- Каждому
ЗаписатьНачалоЭлементадолжен соответствовать свойЗаписатьКонецЭлемента— платформа закрывает именно текущий открытый тег. Закрытьсбрасывает буфер в файл. Без него данные могут остаться недописанными.
Если нужно получить 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
Разберём то, что встречается чаще всего и с чем код падает не сразу.
UTF-8 и в ОткрытьФайл, и в ЗаписатьОбъявлениеXML, и проверьте, что принимающая система ждёт ту же кодировку.Закрыть у объекта ЗаписьXML, либо остался незакрытый ЗаписатьНачалоЭлемента. Проверьте, что число открытий и закрытий элементов совпадает.Текст, а не в НачалоЭлемента. Значение берут на узле ТипУзлаXML.Текст через свойство Значение, а не сразу на открывающем теге.targetNamespace схемы — до символа. Скопируйте URI прямо из XSD, а не набирайте вручную.Отдельно про память: потоковые ЧтениеXML и ЗаписьXML работают с файлом любого размера, потому что держат в памяти только текущий узел. А вот загрузка всего файла в DOM или в одну строку через УстановитьСтроку на больших выгрузках (сотни мегабайт) может упереться в память рабочего процесса — для таких объёмов оставайтесь на потоковом разборе.
Частые вопросы
Чем XDTO-сериализация отличается от ручного ЧтениеXML/ЗаписьXML?
В какой кодировке сохранять XML для обмена?
UTF-8 — её понимают почти все системы. Главное, чтобы кодировка в ОткрытьФайл совпадала с той, что указана в объявлении XML и ожидается на принимающей стороне.Можно ли читать XML из строки, а не из файла?
ЧтениеXML есть метод УстановитьСтроку, который принимает текст XML напрямую — это удобно для ответов веб-сервисов, пришедших строкой, без записи во временный файл.Поддерживает ли 1С выборку по XPath?
ПостроительDOM, ДокументDOM): она загружает файл деревом и позволяет обращаться к узлам, в том числе через выражения XPath.Обязательно ли импортировать XSD в конфигурацию?
ЧтениеСхемыXML и построить фабрику функцией создания фабрики XDTO прямо во время выполнения. Импорт в «Пакеты XDTO» удобен, когда формат стабильный и типы нужны по всей конфигурации.