Как правильно создать и заполнить вложенные объекты в СписокXDTO при выгрузке по схеме XSD

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

При интеграции 1С с внешними системами через XML часто используются готовые схемы валидации XSD. Для работы с ними платформа 1С:Предприятие предоставляет удобный объект ФабрикаXDTO. Однако при программном формировании иерархических структур данных разработчики нередко сталкиваются с трудностями при заполнении вложенных списков и коллекций, получая ошибки вроде «Индекс находится за границами массива» или «Недостаточно фактических параметров».

Разберем типичную проблему и выясним причины ее возникновения, а также рассмотрим пошаговый алгоритм правильного заполнения многоуровневых структур данных XDTO.

Анализ проблемы: почему возникает ошибка обращения по индексу

Рассмотрим типовую ситуацию: в схеме XSD описан сложный тип (например, EmployeePaymentsType), содержащий свойство ListOfDeduction, внутри которого находится список элементов вычетов Deductions с реквизитами Deduction и Amount.

Частая ошибка заключается в попытке обратиться к первому элементу вложенного списка напрямую через индекс сразу после создания родительского объекта:


Вычеты = ФабрикаXDTO.Создать(ФабрикаXDTO.Пакеты.Получить("http://test").Получить("EmployeePaymentsType").Свойства.Получить("ListOfDeduction").Тип);
Вычеты.Deductions[0].Deduction = "dddd"; // Вызовет ошибку "Индекс находится за границами массива"

Проанализируем, почему этот код не работает:

  1. При создании родительского объекта свойство Deductions инициализируется как пустая коллекция типа СписокXDTO. В ней еще нет ни одной строки, поэтому обращение к [0] приводит к выходу за границы массива.
  2. Попытка вызвать метод Вычеты.Deductions.Добавить() без параметров также приводит к ошибке «Недостаточно фактических параметров», поскольку метод Добавить() у объекта СписокXDTO обязательно ожидает готовый экземпляр значения или вложенного объекта типа ОбъектXDTO.

Пошаговый алгоритм создания и заполнения вложенных элементов XDTO

Разберем по шагам, как корректно инициализировать и наполнять вложенные списки XDTO любого уровня вложенности.

  1. Получаем тип дочернего элемента. В зависимости от структуры схемы XSD, тип элемента списка может быть глобальным (именованным типом пакета) либо локальным (анонимным типом свойства внутри родительского объекта). Для глобального типа используем метод ФабрикаXDTO.Тип(URI, ИмяТипа), а для локального — получаем его через метаданные свойства родителя: ОбъектРодитель.Свойства.Получить("ИмяСвойства").Тип.
  2. Создаем экземпляр дочернего объекта. Передаем полученный тип в метод ФабрикаXDTO.Создать(ТипЭлемента).
  3. Заполняем реквизиты созданного объекта. Присваиваем значения полям созданного экземпляра.
  4. Добавляем объект в родительскую коллекцию. Вызываем метод Добавить() у свойства-списка, передавая ему подготовленный экземпляр: СписокXDTO.Добавить(НовыйЭлемент).

Пример программного формирования иерархии XDTO

Посмотрим на практический пример кода, который формирует дерево элементов и корректно заполняет вложенные реквизиты:


// 1. Создаем родительский объект
URIПространства = "http://test";
ТипПлатежей = ФабрикаXDTO.Тип(URIПространства, "EmployeePaymentsType");
ПлатежиСотрудника = ФабрикаXDTO.Создать(ТипПлатежей);

// 2. Создаем контейнер для вычетов (ListOfDeduction)
ТипСпискаВычетов = ПлатежиСотрудника.Свойства.Получить("ListOfDeduction").Тип;
Вычеты = ФабрикаXDTO.Создать(ТипСпискаВычетов);

// 3. Получаем тип отдельной строки вычета (Deductions)
ТипСтрокиВычета = Вычеты.Свойства.Получить("Deductions").Тип;

// 4. Создаем и заполняем строки списка
Для Каждого СтрокаТЧ Из ТаблицаДанных Цикл
    СтрокаВычета = ФабрикаXDTO.Создать(ТипСтрокиВычета);
    СтрокаВычета.Deduction = СтрокаТЧ.КодВычета;
    СтрокаВычета.Amount = СтрокаТЧ.СуммаВычета;
    
    // Помещаем созданный объект в коллекцию СписокXDTO
    Вычеты.Deductions.Добавить(СтрокаВычета);
КонецЦикла;

// 5. Привязываем контейнер вычетов к родительскому объекту
ПлатежиСотрудника.ListOfDeduction = Вычеты;

Проверка и запись сформированных данных в XML-файл

После того как структура XDTO полностью заполнена данными, выполним проверку корректности и сформируем итоговый файл выгрузки.

  1. Валидация структуры. Метод ФабрикаXDTO.Проверить(ОбъектXDTO) позволяет убедиться, что все обязательные поля (согласно правилам XSD) заполнены, типы соответствуют ограничениям, а количество элементов в списках не нарушает спецификацию.
  2. Сериализация в XML. Запись выполняется с помощью объекта ЗаписьXML и метода ФабрикаXDTO.ЗаписатьXML():

// Проверяем соответствие схеме XSD
ФабрикаXDTO.Проверить(ПлатежиСотрудника);

// Записываем результат на диск
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\Exchange\Export.xml", "UTF-8");
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ПлатежиСотрудника);
ЗаписьXML.Закрыть();

Альтернативные способы формирования XML

В случаях, когда схема XSD имеет чрезмерно сложную и запутанную структуру со множеством анонимных типов, разработка через ФабрикаXDTO может оказаться трудоемкой. В таких ситуациях рассмотрим альтернативные подходы:

  1. Прямая генерация через ЗаписьXML. Формирование документа методами ЗаписатьНачалоЭлемента(), ЗаписатьТекст(), ЗаписатьАтрибут() и ЗаписатьКонецЭлемента(). Этот способ работает быстрее по производительности и не требует динамического определения типов.
  2. Использование объектной модели DOM (ДокументDOM). Позволяет формировать XML-дерево из узлов и элементов в памяти произвольным образом без строгой типизации XDTO.
← На главную