Работа с механизмом XDTO (XML Data Transfer Objects) является стандартом для интеграции современных конфигураций 1С с внешними системами. Однако начинающие разработчики часто сталкиваются с двумя проблемами: необходимостью вручную приводить типы (например, конвертировать строку в число) и обилием конструкций Попытка...Исключение при обращении к необязательным полям XML. Разберем, как оптимизировать эти алгоритмы и сделать код более надежным и производительным.
Часто при чтении XML через ФабрикаXDTO.ПрочитатьXML(ЧтениеXML) разработчик получает объект, где все значения полей представлены в виде строк, даже если в XSD-схеме указано, что это decimal или dateTime. В результате приходится использовать функции вида XMLЗначение(Тип("Число"), ОбъектXDTO.Поле). Это происходит потому, что при «бестиповом» чтении 1С не сопоставляет входящие данные с конкретным описанием из пакета XDTO.
Чтобы 1С автоматически преобразовывала типы данных, необходимо явно указывать тип объекта при вызове метода чтения. Проанализируем правильный подход:
// 1. Получаем тип из фабрики XDTO, используя URI пространства имен и имя типа
ТипОбъекта = ФабрикаXDTO.Тип("http://www.your-company.com/v1/stock", "Stock");
// 2. Читаем XML, передавая вторым параметром ожидаемый тип
// Теперь 1С знает структуру и типы данных из схемы
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML, ТипОбъекта);
// 3. Обращаемся к свойствам напрямую — они уже имеют правильный тип (Число, Дата и т.д.)
ОбщийОбъем = ОбъектXDTO.volume + 100; // Ошибки не будет, так как volume уже число
При таком подходе 1С выполняет десериализацию в строгом соответствии со схемой. Если в XSD указано xsd:decimal, в свойстве объекта XDTO вы сразу получите тип Число. Это избавляет от лишних преобразований и делает код чище.
Вторая распространенная проблема — ошибка «Поле объекта не обнаружено» при обращении к свойствам, которые помечены в схеме как необязательные (minOccurs="0"). Если тег отсутствует в XML-файле, прямое обращение через точку вызывает исключение. Использование Попытка...Исключение существенно замедляет работу системы, особенно при массовой обработке данных.
Рассмотрим два эффективных способа решения этой задачи:
Способ 1. Использование метода ПроверитьУстановлено()
Это самый быстрый и «правильный» с точки зрения платформы 1С метод. Он позволяет проверить наличие значения, не вызывая исключений:
// Проверяем, заполнено ли свойство "Part3" в объекте Title
Если ОбъектTitle.ПроверитьУстановлено("Part3") Тогда
Значение = ОбъектTitle.Part3;
Иначе
Значение = Неопределено;
КонецЕсли;
Способ 2. Предварительная инициализация типа
Как мы уже выяснили выше, если при чтении XML передать в метод ПрочитатьXML объект типа (ТипОбъектаXDTO), 1С создаст структуру объекта полностью. Для всех отсутствующих в файле свойств, которые описаны в схеме, 1С создаст «заглушки». При обращении к ним через точку вы просто получите Неопределено вместо ошибки. Это позволяет писать лаконичный код без лишних проверок.
Важно понимать разницу в поведении системы в зависимости от описания в XSD:
Неопределено.xsi:nil="true". В 1С это также вернет Неопределено.<tag/> или <tag></tag>. Если тип строковый, вернется пустая строка "".Если вам неудобно работать с объектами XDTO напрямую, можно воспользоваться механизмом СериализаторXDTO. Этот подход часто применяется в «Конвертации данных 3.0». Мы можем преобразовать XDTO-объект в привычную 1С-структуру:
// Преобразование XDTO в универсальную коллекцию (структуру или соответствие)
ДанныеСписка = СериализаторXDTO.ПрочитатьXDTO(ОбъектXDTO);
// Теперь можно использовать ЗаполнитьЗначенияСвойств или обращаться к свойствам структуры
// В структуре будут все ключи, соответствующие свойствам XDTO
Если ДанныеСписка.Свойство("Part1") Тогда
// Работаем с данными
КонецЕсли;
Однако стоит учитывать, что при глубокой вложенности объектов создание структур может быть более ресурсоемким процессом, чем прямая работа с ОбъектXDTO.
Вместо того чтобы вручную проверять каждое поле на соответствие типам или длине строки, воспользуемся встроенным методом валидации. Это особенно полезно перед записью данных в базу или отправкой внешнему потребителю.
Попытка
ОбъектXDTO.Проверить();
Сообщить("Объект соответствует схеме XSD");
Исключение
Сообщить("Ошибка валидации: " + ОписаниеОшибки());
КонецПопытки;
Метод Проверить() автоматически сверяет данные с фасетами схемы (ограничения по длине, регулярные выражения, обязательность заполнения), что значительно сокращает объем кода для проверок.
Проанализировав возможности XDTO-фабрики, можно выделить следующие правила хорошего тона при разработке интеграций:
Попытка.ОбъектXDTO.Тип().Свойства, чтобы понять, какие данные пришли в текущем пакете.ЧтениеXML, чтобы найти нужный узел, и только его превращайте в ОбъектXDTO.