Работа с технологией XDTO (XML Data Transfer Objects) в 1С:Предприятии часто вызывает затруднения у начинающих разработчиков. Одной из самых распространенных проблем является ситуация, когда при попытке получить тип объекта из фабрики метод Тип() возвращает Неопределено, хотя пакет загружен или создан в конфигурации. В этой статье мы разберем, почему это происходит, рассмотрим разницу между типами и корневыми свойствами, а также научимся проверять типы данных на "заполненность".
Для начала проанализируем ситуацию: разработчик пытается получить доступ к структуре данных с помощью кода: ФабрикаXDTO.Тип("http://www.dis.test.org", "HBECONOMUNITS"), но в результате получает пустое значение. Выясним причину такого поведения системы.
В структуре XSD-схемы (на которой базируется XDTO) существует четкое разделение между двумя категориями объектов:
Метод ФабрикаXDTO.Тип() ищет только в секции типов. Если HBECONOMUNITS в вашей схеме определен как глобальный элемент (Element), а не как именованный тип (ComplexType), то метод Тип() его не найдет. Это фундаментальная особенность архитектуры XDTO в 1С.
Если мы столкнулись с тем, что нам нужно создать объект на основании глобального элемента схемы, мы должны обратиться к коллекции пакетов фабрики. Рассмотрим правильный алгоритм получения типа:
// 1. Получаем пакет по его пространству имен (Namespace URI)
Пакет = ФабрикаXDTO.Пакеты.Получить("http://www.dis.test.org");
// 2. Ищем элемент в коллекции корневых свойств
ОписаниеСвойства = Пакет.КорневыеСвойства.Получить("HBECONOMUNITS");
// 3. Теперь мы можем получить тип этого свойства
ТипОбъекта = ОписаниеСвойства.Тип;
// 4. Создаем объект на основании полученного типа
НовыйОбъект = ФабрикаXDTO.Создать(ТипОбъекта);
Обратите внимание, что обращение к КорневыеСвойства позволяет "достучаться" до тех элементов, которые являются заголовками документов в XML. Если же вам нужно работать с внутренними структурами, которые описаны как ComplexType, тогда метод ФабрикаXDTO.Тип() будет работать корректно.
Рассмотрим следующую задачу: при обходе структуры XDTO-объекта нам нужно понять, имеем ли мы дело с простым значением (строка, число) или со сложным вложенным объектом. В объектной модели XDTO для этого используются свойства описания свойств.
Проанализируем программную проверку вида типа. Для этого у типа объекта существует свойство ВидТипаXDTO, которое может принимать значения из системного перечисления.
// Допустим, у нас есть описание свойства СвойствоXDTO
Если СвойствоXDTO.Тип.ВидТипаXDTO = ВидТипаXDTO.Атомарный Тогда
// Это простое значение (строка, дата, число и т.д.)
// Здесь будет заполнено СвойствоXDTO.Тип (как ТипЗначенияXDTO)
Сообщить("Это простое значение");
ИначеЕсли СвойствоXDTO.Тип.ВидТипаXDTO = ВидТипаXDTO.Составной Тогда
// Это сложный объект (ComplexType)
Сообщить("Это сложная структура (объект)");
КонецЕсли;
Если вы работаете с наследованием в XSD, вам может потребоваться свойство БазовыйТип. Оно позволяет определить, от какого типа унаследовано текущее свойство, что крайне полезно при обработке схем с расширениями (extension).
Разберем несколько критически важных моментов, которые помогут избежать ошибок при интеграции:
"http://test.org" и "HTTP://test.org" для фабрики являются абсолютно разными. Всегда копируйте URI непосредственно из текста XSD-файла или свойств пакета в конфигураторе.maxOccurs больше 1 (или unbounded), то в 1С это свойство всегда будет возвращать объект СписокXDTO. Даже если в конкретном XML-файле пришел всего один элемент, попытка обратиться к нему как к одиночному объекту вызовет ошибку. Проверить это можно через СвойствоXDTO.ВерхняяГраница.ФабрикаXDTO.Проверить(ОбъектXDTO). Это позволит на этапе отладки выявить несоответствие типов, отсутствие обязательных полей или нарушение ограничений по длине строк.Иногда прямой путь через создание типов в фабрике оказывается слишком трудоемким. Если ваша задача — преобразовать стандартный объект 1С (например, документ или справочник) в формат XML, соответствующий схеме, рассмотрите использование Сериализатора XDTO.
Проанализируем пример кода:
// Пример быстрой записи объекта 1С в формат XDTO
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Сериализатор использует текущую фабрику для сопоставления
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, СсылкаНаОбъект);
РезультатXML = ЗаписьXML.Закрыть();
Этот метод работает эффективно только в том случае, если типы в вашем XDTO-пакете соответствуют именам и структуре метаданных 1С. В противном случае "ручная" сборка объекта через ФабрикаXDTO.Создать() остается единственным верным решением.
Подводя итог, помните: если ФабрикаXDTO.Тип() не видит ваш объект, в 99% случаев он просто является Корневым свойством пакета. Используйте коллекцию Пакет.КорневыеСвойства, проверяйте ВидТипаXDTO для определения вложенности и всегда следите за точностью написания URI пространств имен.