Механизм XDTO (XML Data Transfer Objects) предназначен для описания структуры передаваемых данных с помощью стандартов XML Schema (XSD) и последующей сериализации объектов. Среди разработчиков нередко возникает вопрос: является ли XDTO обязательным инструментом платформы или абсолютно любую интеграцию можно реализовать классическими методами через ручной разбор текстовых форматов? Проанализируем архитектуру платформы, выясним сценарии жесткой технической необходимости XDTO и разберем практические приемы эффективной работы со схемами.
Существуют задачи, в которых обойтись без объектов XDTO невозможно из-за требований системной архитектуры 1С:
ОбъектXDTO.Когда речь заходит о файловом обмене (произвольные XML-файлы, интеграция со сторонними учетными системами, государственными порталами, таможней и т.д.), теоретически задачу можно решить потоковым чтением ЧтениеXML или текстовыми методами. Однако применение XDTO дает существенные преимущества:
ЧтениеXML разработчик получает исключительно строковые значения. Приходится вручную приводить каждое поле к нужному типу (вызывать Число(), Дата(), парсить булевы флаги и GUID). Фабрика XDTO берет это на себя: даты автоматически становятся датами 1С, числа — числами, а булево — типом Булево.ФабрикаXDTO.Проверить() можно проверить входящий или исходящий XML-документ на соответствие ограничениям схемы (длина строк, регулярные выражения, обязательность заполнения, диапазоны чисел). Это исключает необходимость написания сотен строк валидационного кода вручную.ФабрикаXDTO.ПрочитатьJSON() и ФабрикаXDTO.ЗаписатьJSON() позволяют использовать строгие XSD-схемы для работы с форматом JSON, компенсируя отсутствие в JSON нативного типа даты и предотвращая искажения типов.Часто внешние ведомства (например, таможенные органы или налоговые службы) предоставляют спецификации, состоящие из сотен взаимосвязанных XSD-файлов. Добавление 400 и более пакетов в дерево метаданных конфигурации неоправданно раздувает конфигурацию и усложняет поддержку. В этом случае правильным подходом является хранение архива схем во внешнем файле или общем макете с последующим программным созданием фабрики через метод СоздатьФабрикуXDTO().
Рассмотрим пример функции, которая извлекает набор схем XSD из макета с ZIP-архивом и формирует фабрику XDTO:
Функция ПолучитьФабрикуXDTOИзМакета(ИмяМакета = "СхемыОбмена") Экспорт
ДанныеМакета = ПолучитьМакет(ИмяМакета);
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("zip");
ДанныеМакета.Записать(ИмяВременногоФайла);
Чтение = Новый ЧтениеZipФайла(ИмяВременногоФайла);
ИмяВременногоКаталога = ПолучитьИмяВременногоФайла("");
СоздатьКаталог(ИмяВременногоКаталога);
Чтение.ИзвлечьВсе(ИмяВременногоКаталога, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Файлы = НайтиФайлы(ИмяВременногоКаталога, "*.xsd", Истина);
МассивСхем = Новый Массив();
Для Каждого Файл Из Файлы Цикл
МассивСхем.Добавить(Файл.ПолноеИмя);
КонецЦикла;
Фабрика = СоздатьФабрикуXDTO(МассивСхем);
// Удаляем временные файлы после успешной компиляции фабрики
УдалитьФайлы(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоКаталога);
Возврат Фабрика;
КонецФункции
После получения фабрики разбор входящего XML-файла сводится к вызову чтения, после чего все реквизиты становятся доступны через свойства типизированного объекта XDTO:
Фабрика = ПолучитьФабрикуXDTOИзМакета();
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("C:\Exchange\CustomsData.xml");
ОбъектДанных = Фабрика.ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();
// Обращение к свойствам объекта без ручного парсинга типов
НомерДекларации = ОбъектДанных.DeclarationNumber;
ДатаРегистрации = ОбъектДанных.RegistrationDate; // Уже является типом Дата
СуммаПлатежа = ОбъектДанных.TotalAmount; // Уже является типом Число
Несмотря на очевидные преимущества, существуют сценарии, в которых применение XDTO является неэффективным или технически невозможным:
Фабрика.ПрочитатьXML() загружает всё дерево документа в оперативную память целиком (подобно модели DOM). Для файлов большого размера это неизбежно приводит к ошибке «Недостаточно памяти» и аварийному завершению сеанса. В таких случаях необходимо использовать потоковое последовательное чтение через объект ЧтениеXML.СоздатьФабрикуXDTO() требует ощутимого времени на валидацию и компиляцию схем. Недопустимо вызывать создание динамической фабрики в цикле или при каждом входящем HTTP/SOAP-запросе без кэширования (например, фабрику следует кэшировать в модуле с повторным использованием возвращаемых значений).