XDTO в 1С: XML или JSON — что выбрать и как сериализовать

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

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

Скачать конфигурацию

Запишись на тренинг

НАУЧИСЬ РАБОТАТЬ С XDTO В 1С ЗА ОДНО ЗАНЯТИЕ ЗАПИСАТЬСЯ

В конфигурации есть справочник номенклатура. Вот его мы и будем выгружать. Есть кнопка генерации номенклатуры, количество позиций вы можете задать в коде.

Перед каждым тестом я рекомендую перезапускать конфигурацию. Результаты всех тестов в миллисекундах .

Выгрузка загрузка JSON

После подготовки базы. Вы можете посмотреть скорость выгрузки просто в JSON. С помощью ЗаписьJSON и ЗаписатьJSON. Тут правда надо понимать, что данные для такой выгрузки надо предварительно корректно сформировать.

У меня на 10 000 позиций номенклатуры получился вот такой результат:

Выборка = 808 
Формирование JSON = 41 

Теперь сразу загрузим данный файл обратно.

Десериализация JSON = 53 
Запись JSON = 13 401 

Можно ускорить загрузку, загружая в транзакции.

Десериализация JSON = 53 
Запись JSON = 7 171 

ФабрикаXDTO. Выгрузка загрузка XML

Теперь попробуем выгрузить тот же справочник с помощью ФабрикаXDTO. Используя данный метод, нам приходится тратить лишнее время на получение объектов из базы. Получается запрос в цикле. Но мы получаем очень простой и удобный код.

Результаты выгрузки в XML:

Выборка = 3 314 
Формирование XDTO (XML) = 288 

Загрузим файл обратно.

Десериализация XDTO (XML) = 3 187 
Запись XDTO (XML) = 51 830 

Ускорим загрузку в транзакции.

Десериализация XDTO (XML) = 3 238 
Запись XDTO (XML) = 6 108 

Результат в транзакции просто отличный.

СериализаторXDTO. Выгрузка загрузка JSON

Тоже самое, что и с фабрикой. Но мы получаем простой код, формат JSON и привязку к типам. Результаты выгрузки можете видеть ниже.

Выборка = 3 595 
Формирование XDTO (JSON) = 97 

И обратная загрузка.

Десериализация XDTO (JSON) = 3 158 
Запись XDTO (JSON) = 50 986 

И в транзакции.

Десериализация XDTO (JSON) = 3 069 
Запись XDTO (JSON) = 6 231 

Вывод

Самый быстрый режим оказался JSON, как по выгрузке, так и по загрузке. Его удобно применять при обмене с сайтом. Но подготовка данных и их обратная загрузка значительно увеличивает код.

Сериализация и десериализация объектов в XML и JSON в принципе сопоставимы. Удобно выгружать и загружать данные. Внутри файлов содержится информация о типах. И если при загрузке данных особой разницы не видно, то при сериализации в JSON мы видим кратное ускорение, плюс этот JSON вполне легко преобразовать на стороне сайта.

Выбор инструментов за вами, и не забываем режим загрузки в транзакции, что дает сильный прирост производительности.

Из объекта 1С в XDTO, XML и JSON: код

Выше — цифры, ниже — сам код, которым эти цифры получены. Базовый приём один и тот же для XML и XDTO-JSON: сначала объект 1С превращается в промежуточный ОбъектXDTO через СериализаторXDTO, а дальше этот ОбъектXDTO записывается либо в XML через ФабрикаXDTO, либо напрямую в JSON.

Сериализация ссылки или объекта в XML:

// Объект 1С (ссылка, документ, элемент справочника) -> ОбъектXDTO
ОбъектXDTO = СериализаторXDTO.ЗаписатьXDTO(ТекущийОбъект);

// ОбъектXDTO -> строка XML
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
ФабрикаXDTO.ЗаписатьXML(Запись, ОбъектXDTO);
СтрокаXML = Запись.Закрыть();

Обратная загрузка XML в базу:

// Строка XML -> ОбъектXDTO
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаXML);
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);

// ОбъектXDTO -> объект 1С, который уже можно записать в базу
ВосстановленныйОбъект = СериализаторXDTO.ПрочитатьXDTO(ОбъектXDTO);
ВосстановленныйОбъект.Записать();

Начиная с платформы 8.3.7.1759 СериализаторXDTO умеет писать прикладные типы сразу в JSON, без промежуточного ОбъектXDTO и без ручной сборки структуры — в этом его отличие от связки ЗаписьJSON + ЗаписатьJSON из раздела выше:

// Объект 1С -> строка JSON напрямую
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
// НазначениеТипаXML.Явное сохраняет в JSON информацию о типе значения,
// иначе на приёмнике тип нужно знать заранее
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ТекущийОбъект, НазначениеТипаXML.Явное);
СтрокаJSON = ЗаписьJSON.Закрыть();

И обратно — из JSON в объект 1С:

// Строка JSON -> объект 1С
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ВосстановленныйОбъект = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON, Тип("СправочникСсылка.Номенклатура"));

Разница с обычным ЗаписьJSON из раздела «Выгрузка загрузка JSON» принципиальная: там нужно вручную собрать структуру (Соответствие, массив) с нужными полями, здесь СериализаторXDTO сам обходит реквизиты объекта — платите за это чуть большим временем сериализации (97 мс против 41 мс на 10 000 позиций в замере выше).

Фабрика XDTO на своей XSD-схеме

В примерах выше типы брались из глобальной ФабрикаXDTO — она знает встроенные типы платформы и типы XDTO-пакетов, объявленных в конфигураторе. Но схему можно не описывать в конфигурации, а хранить как внешний файл XSD (например, в справочнике, в реквизите ХранилищеЗначения) и строить ФабрикаXDTO из неё прямо в коде. Это выручает, когда формат навязан внешней системой и меняется без перевыпуска конфигурации.

Схема читается в DOM, из него собирается набор схем, а по нему создаётся независимая фабрика — её типов нет в глобальной ФабрикаXDTO, и наоборот:

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайлаСхемы);

ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);

ПостроительСхемыXML = Новый ПостроительСхемXML;
СхемаXML = ПостроительСхемыXML.СоздатьСхемуXML(ДокументDOM);

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

// Независимая фабрика на основе внешней схемы
НоваяФабрикаXDTO = Новый ФабрикаXDTO(НаборСхемXML);

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

Идемпотентный импорт XDTO-пакета в базу

Сериализовать объекты — половина дела; на приёмнике пакет нужно разобрать и записать в базу так, чтобы повторный импорт того же файла не плодил дубли. Ключевой приём — проверка существования ссылки перед созданием элемента плюс УстановитьСсылкуНового, который сохраняет тот же GUID: при повторном обмене объект найдётся и второй раз не создастся.

Процедура ЗаписатьНоменклатуру(Данные)
    // Несуществующая ссылка вернёт Неопределено — только тогда создаём элемент
    Если Данные.Ref.ПолучитьОбъект() = Неопределено Тогда
        НовыйОбъект = Справочники.Номенклатура.СоздатьЭлемент();
        НовыйОбъект.УстановитьСсылкуНового(Данные.Ref);
        ЗаполнитьЗначенияСвойств(НовыйОбъект, Данные);
        НовыйОбъект.Записать();
    КонецЕсли;
КонецПроцедуры

За кадром остаётся ещё несколько тонкостей боевого импорта: один элемент приходит как ОбъектXDTO, а несколько — как СписокXDTO, и диспетчер должен обработать оба случая; ссылки на владельца и табличные части разбираются отдельно; проверки существования лучше не строить на поиске подстроки в тексте ошибки (локале-зависимо). Полный разбор пакета по всем справочникам и документам, с надёжными идемпотентными проверками, — на курсе «XDTO в 1С».

Как прочитать JSON-строку в структуру или соответствие 1С

Частый случай на практике: с сайта или из внешнего REST API пришла строка JSON заранее известного формата, и восстанавливать полноценный объект 1С через СериализаторXDTO не нужно — достаточно получить данные в Структуре или Соответствии. Для этого есть глобальная функция ПрочитатьJSON, безо всякого XDTO.

Оборачиваем строку в ЧтениеJSON и читаем. Второй параметр ПрочитатьJSON задаёт форму результата: Ложь — вернётся Структура (обращение по Данные.name), Истина — Соответствие (обращение по Данные["name"]):

// Строка JSON -> Структура (или Соответствие)
СтрокаJSON = "{""name"":""Мышь"",""price"":790,""active"":true}";

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);

// Ложь -> Структура, Истина -> Соответствие
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь);
ЧтениеJSON.Закрыть();

Сообщить(Данные.name);   // Мышь
Сообщить(Данные.price);  // 790

Соответствие берут, когда ключи JSON не годятся в имена реквизитов 1С (содержат дефис, пробел или начинаются с цифры) — к Структуре по такому ключу не обратиться, а к Соответствию можно: Данные["some-key"].

Если JSON лежит в теле HTTP-запроса (обмен с сайтом через HTTP-сервис), строку берут прямо из запроса:

ДанныеJSON = Запрос.ПолучитьТелоКакСтроку();
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ДанныеJSON);
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь);

Отдельная грабля — даты. JSON не знает тип «дата», поэтому без подсказки все даты придут строками. Третий параметр ПрочитатьJSON — массив имён свойств, которые надо разобрать как дату по ISO:

ИменаДат = Новый Массив;
ИменаДат.Добавить("date");
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь, ИменаДат);

Итого: СериализаторXDTO.ПрочитатьJSON из раздела выше нужен, когда на выходе должен получиться объект 1С; а глобальный ПрочитатьJSON — когда достаточно данных в Структуре или Соответствии. Для обмена с сайтом почти всегда хватает второго.

XML, JSON или XDTO: что выбрать для интеграции 1С

Короткий ответ — зависит от того, кто на другом конце обмена и нужна ли типизация на лету:

КритерийXML через ФабрикаXDTOОбычный JSON (ЗаписьJSON/ЧтениеJSON)XDTO в JSON (СериализаторXDTO.ЗаписатьJSON)
Когда применятьОбмен с ЕГАИС, СБИС, ЭДО и другими системами со строгой XML-схемой; SOAP-веб-сервисыОбмен с сайтом, мобильным приложением или внешним REST API по заранее согласованному форматуОбмен между базами 1С или с сервисом, готовым принимать типизированный JSON без ручного описания структуры
Типизация и валидацияСтрогая, по XSD-схеме — несовместимые данные не сериализуютсяНет — структуру и типы полей контролирует только кодЕсть, через XDTO-типы, но без XSD-схемы
Подготовка данных перед записьюНе нужна для ссылок и объектов — сериализатор сам берёт реквизитыНужна — структуру для ЗаписьJSON собирают вручнуюНе нужна — ссылку или объект можно передать напрямую
Скорость сериализации (тест на 10 000 позиций из этой статьи)288 мс41 мс97 мс
Совместимость на стороне приёмникаМаксимальная — XML понимает практически любая системаМаксимальная среди веб-форматов, но разбор структуры всегда ручнойХорошая для обмена 1С-1С; для внешних систем не даёт преимуществ перед обычным JSON

На практике для сайта и мобильного клиента почти всегда выигрывает обычный JSON — он самый компактный и быстрый, а формат заранее известен обеим сторонам. XDTO в XML имеет смысл только там, где формат навязан снаружи (ЕГАИС, СБИС, старые SOAP-интеграции) или нужна валидация по схеме. XDTO в JSON — рабочий компромисс для обмена между базами 1С, когда лень вручную готовить структуру, но лишний слой типизации на внешнем REST API не нужен.

Похожие статьи

Практический курс по XDTO

Если хочется не просто прочитать про XDTO, а за одно занятие разобрать сериализацию, обмен с сайтом и типовые ошибки на реальном коде — приходите на курс «XDTO в 1С».

А если нужен более широкий разбор интеграции 1С — HTTP-сервисы, обмен данными, типовые архитектурные решения — на эту задачу отвечает курс «Интеграция 1С для начинающих».

А когда обмен настроен, следующий логичный шаг — поручить сериализацию и разбор входящего JSON ИИ-агенту для 1С: он пишет такой код сам. Как это устроено — на курсе по ИИ-агентам, RAG и MCP-серверам.

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