Как настроить XDTO-пакет в 1С для выгрузки линейного списка элементов вместо вложенного?

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

При интеграции 1С с внешними сайтами, CRM-системами или веб-сервисами разработчики часто сталкиваются с жесткими требованиями к структуре принимаемого XML. Стандартные пакеты обмена (например, CommerceML) используют строго структурированный формат, где списки объектов всегда обернуты в промежуточные теги. Однако многие веб-ресурсы требуют более простой, "плоский" вид данных.

В этой статье мы подробно разберем, как изменить структуру XDTO-пакета в конфигураторе 1С, чтобы вместо вложенной структуры с промежуточными тегами получить линейный список элементов внутри родительского контейнера. Мы также научимся правильно заполнять такую структуру в коде 1С и разберем типичные ошибки, которые могут возникнуть при настройке.

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

По умолчанию при выгрузке списков (например, товаров или их кодов) платформа 1С генерирует вложенную XML-структуру:


<Products>
    <Product>
        <Code>7b370a43-35ca-11e9-810c-704d7b85cadd</Code>
    </Product>
    <Product>
        <Code>2ee45d3d-35cb-11e9-810c-704d7b85cadd</Code>
    </Product>
</Products>

Здесь тег Products выступает в роли общей коллекции, тег Product обозначает отдельный объект-строку, а тег Code — конкретное свойство этого объекта. Наша задача — избавиться от промежуточного тега Product и получить линейный массив простых значений напрямую внутри родительского тега:


<Products>
    <Code>7b370a43-35ca-11e9-810c-704d7b85cadd</Code>
    <Code>2ee45d3d-35cb-11e9-810c-704d7b85cadd</Code>
</Products>

Давайте пошагово разберем, как настроить XDTO-пакет для достижения этого результата.

Шаг 1. Настройка типа объекта в XDTO-пакете

Чтобы платформа 1С поняла, что внутри тега-контейнера должны находиться не сложные объекты, а повторяющиеся простые значения, нам нужно правильно настроить свойства типа объекта XDTO.

  1. Откройте конфигуратор 1С и перейдите в ваш Пакет XDTO.
  2. Создайте новый Тип объекта (или найдите существующий), который будет представлять наш контейнер. Назовем его, например, ProductsType.
  3. Внутри этого типа создайте новое Свойство и назовем его Code.
  4. Теперь настроим свойства этого реквизита в палитре свойств:
    • Тип (Type): укажите простой тип данных. Для уникальных идентификаторов отлично подойдет стандартный тип string из пространства имен XML-схемы (http://www.w3.org/2001/XMLSchema). Важно: не выбирайте здесь другой объект XDTO, тип должен быть строго простым (типом значения)!
    • Минимальное количество (MinOccurs): укажите 0 (если список может быть пустым) или 1 (если в списке должен быть как минимум один элемент).
    • Максимальное количество (MaxOccurs): укажите значение -1. В терминологии XDTO значение -1 означает "неограниченно". Именно этот параметр указывает платформе 1С, что данное свойство является списком (массивом).

Благодаря этой настройке 1С будет интерпретировать свойство Code как массив простых строк и при сериализации запишет их в XML одну за другой.

Шаг 2. Размещение списка внутри "обложки" (родительского элемента)

Как правило, список Products не отправляется сам по себе, а находится внутри более крупного документа — "обложки" (например, каталога, заказа или справочника). Выясним, как правильно связать наш новый тип с родительским объектом.

  1. В структуре вашего XDTO-пакета найдите тип родительского объекта (например, CatalogType или OrderType).
  2. Добавьте в него новое свойство с именем Products.
  3. В качестве Типа этого свойства выберите ранее созданный нами тип объекта ProductsType.
  4. Для параметров количества укажите Минимальное количество = 1 и Максимальное количество = 1 (так как сам контейнер Products у нас один, а вот коды внутри него будут повторяться).

После этой настройки итоговая структура XML примет следующий, требуемый интеграцией вид:


<Catalog>
    <Products>
        <Code>7b370a43-35ca-11e9-810c-704d7b85cadd</Code>
        <Code>2ee45d3d-35cb-11e9-810c-704d7b85cadd</Code>
    </Products>
</Catalog>

Шаг 3. Заполнение структуры в коде 1С

Работа со свойствами-списками простых типов в коде 1С отличается от работы с обычными объектами XDTO. Поскольку элементами списка являются простые строки, нам не нужно генерировать промежуточные объекты через ФабрикаXDTO.Создать(). Мы должны получить сам список и напрямую добавлять в него строковые значения.

Проанализируем пример кода на встроенном языке 1С:


// 1. Создаем родительский объект (например, Каталог)
КаталогОбъект = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.yourspace.org/cml", "CatalogType"));

// 2. Создаем объект-контейнер для списка товаров
ТоварыОбъект = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("http://www.yourspace.org/cml", "ProductsType"));

// 3. Связываем родительский каталог с созданным контейнером
КаталогОбъект.Products = ТоварыОбъект;

// 4. Получаем список кодов с помощью метода ПолучитьСписок()
// Этот метод обязателен для работы со свойствами, у которых МаксимальноеКоличество = -1
СписокКодов = ТоварыОбъект.ПолучитьСписок("Code");

// 5. Заполняем список кодов простыми строковыми значениями напрямую
СписокКодов.Добавить("7b370a43-35ca-11e9-810c-704d7b85cadd");
СписокКодов.Добавить("2ee45d3d-35cb-11e9-810c-704d7b85cadd");
СписокКодов.Добавить("aec43a0d-35cb-11e9-810c-704d7b85cadd");

Обратите внимание: если попытаться присвоить значение напрямую через свойство (например, написать ТоварыОбъект.Code = "строка"), платформа выдаст ошибку времени выполнения, поскольку свойство-список ожидает работу через специальный метод ПолучитьСписок().

Критически важный нюанс: отличие от типа "Список" (xs:list)

При настройке XDTO-пакетов начинающие разработчики часто путают два принципиально разных механизма работы со списками:

  1. Свойство объекта XDTO с максимальным количеством = -1 (наше решение). Оно создает последовательность полноценных XML-тегов с одинаковыми именами: <Code>Значение1</Code><Code>Значение2</Code>.
  2. Тип значения XDTO с вариантом "Список" (аналог xs:list в XML Schema). Если вы создадите простой тип значения, установите у него галочку "Список" и назначите этот тип свойству Code (оставив его максимальное количество равным 1), то на выходе вы получите один-единственный тег, в котором все значения склеятся через пробел: <Code>7b370a43 2ee45d3d aec43a0d</Code> Такой формат обычно не принимается внешними системами для передачи идентификаторов, поэтому обязательно следите, чтобы списочным было именно Свойство (через свойство Максимальное количество = -1), а не сам Тип.

О "кошерности" и стандартах проектирования XML

В кругах веб-разработчиков и системных архитекторов часто возникают споры о правильности (или "кошерности") плоских списков без промежуточных объектных оберток.

С точки зрения классического проектирования XML-схем (XSD), первый вариант (с вложенным тегом Product) считается правильным и масштабируемым. Объект "Товар" — это сущность. Даже если сейчас вы передаете только его код, в будущем вам может потребоваться передавать наименование, цену или остаток. Наличие промежуточного тега <Product> позволяет легко добавить новые свойства внутрь объекта без изменения логики чтения структуры внешним парсером.

Линейный вариант <Products><Code>...</Code></Products> лишает сущность объектной модели, превращая список товаров в плоский массив строк. Однако для простых интеграций, REST API или систем с дефицитом трафика этот вариант выбирается осознанно, так как он сокращает размер XML-файла и упрощает разбор данных на стороне принимающего скрипта сайта.

Мы успешно решили поставленную задачу, изменили структуру XDTO-пакета в конфигураторе 1С под требования принимающего сайта и научились правильно инициализировать и заполнять списки простых типов в программном коде 1С.

← На главную