Как правильно работать с фабрикой XDTO в 1С и что делать, если метод Тип() возвращает Неопределено

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с технологией XDTO (XML Data Transfer Objects) в 1С:Предприятии часто вызывает затруднения у начинающих разработчиков. Одной из самых распространенных проблем является ситуация, когда при попытке получить тип объекта из фабрики метод Тип() возвращает Неопределено, хотя пакет загружен или создан в конфигурации. В этой статье мы разберем, почему это происходит, рассмотрим разницу между типами и корневыми свойствами, а также научимся проверять типы данных на "заполненность".

Почему метод Тип() возвращает Неопределено?

Для начала проанализируем ситуацию: разработчик пытается получить доступ к структуре данных с помощью кода: ФабрикаXDTO.Тип("http://www.dis.test.org", "HBECONOMUNITS"), но в результате получает пустое значение. Выясним причину такого поведения системы.

В структуре XSD-схемы (на которой базируется XDTO) существует четкое разделение между двумя категориями объектов:

  1. Типы объектов (ComplexType) — это абстрактные описания структуры данных. Они сами по себе не являются элементами XML-документа, а служат шаблонами.
  2. Свойства или Элементы (Elements) — это конкретные "точки входа". Если элемент объявлен на верхнем уровне схемы, он становится корневым свойством. Именно он определяет тег, который будет стоять в самом начале вашего XML-файла.

Метод Фабрика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 = ВидТипаXDTO.Составной Тогда
    // Это сложный объект (ComplexType)
    Сообщить("Это сложная структура (объект)");
КонецЕсли;

Если вы работаете с наследованием в XSD, вам может потребоваться свойство БазовыйТип. Оно позволяет определить, от какого типа унаследовано текущее свойство, что крайне полезно при обработке схем с расширениями (extension).

Важные нюансы при работе с Фабрикой XDTO

Разберем несколько критически важных моментов, которые помогут избежать ошибок при интеграции:

  1. Регистрозависимость: Пространства имен (URI) и имена типов крайне чувствительны к регистру. Строки "http://test.org" и "HTTP://test.org" для фабрики являются абсолютно разными. Всегда копируйте URI непосредственно из текста XSD-файла или свойств пакета в конфигураторе.
  2. Работа со списками: Если в схеме свойство имеет параметр maxOccurs больше 1 (или unbounded), то в 1С это свойство всегда будет возвращать объект СписокXDTO. Даже если в конкретном XML-файле пришел всего один элемент, попытка обратиться к нему как к одиночному объекту вызовет ошибку. Проверить это можно через СвойствоXDTO.ВерхняяГраница.
  3. Валидация данных: Перед отправкой объекта во внешнюю систему или после его заполнения программно, используйте метод ФабрикаXDTO.Проверить(ОбъектXDTO). Это позволит на этапе отладки выявить несоответствие типов, отсутствие обязательных полей или нарушение ограничений по длине строк.

Использование Сериализатора XDTO

Иногда прямой путь через создание типов в фабрике оказывается слишком трудоемким. Если ваша задача — преобразовать стандартный объект 1С (например, документ или справочник) в формат XML, соответствующий схеме, рассмотрите использование Сериализатора XDTO.

Проанализируем пример кода:


// Пример быстрой записи объекта 1С в формат XDTO
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

// Сериализатор использует текущую фабрику для сопоставления
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, СсылкаНаОбъект);

РезультатXML = ЗаписьXML.Закрыть();

Этот метод работает эффективно только в том случае, если типы в вашем XDTO-пакете соответствуют именам и структуре метаданных 1С. В противном случае "ручная" сборка объекта через ФабрикаXDTO.Создать() остается единственным верным решением.

Подводя итог, помните: если ФабрикаXDTO.Тип() не видит ваш объект, в 99% случаев он просто является Корневым свойством пакета. Используйте коллекцию Пакет.КорневыеСвойства, проверяйте ВидТипаXDTO для определения вложенности и всегда следите за точностью написания URI пространств имен.

← На главную