Как обновить схему CommerceML и заполнить группы классификатора через XDTO в 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При интеграции конфигураций 1С (например, Управление торговлей 10.3) с сайтами и интернет-магазинами на базе 1С-Битрикс часто возникает необходимость перехода на более свежую версию формата CommerceML (с версии 2.08 на 2.10 и выше). В процессе доработки типовых выгрузок разработчики регулярно сталкиваются с двумя сложностями: ограничением платформы на уникальность пространств имен XDTO-пакетов и особенностями программного заполнения древовидной структуры каталога и групп классификатора.

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

Ограничение пространств имен XDTO в дереве метаданных

Проанализируем структуру пакетов XDTO в дереве метаданных конфигурации. В стандарте CommerceML версии 2.08, 2.09 и 2.10 используется единый целевой URI пространства имен:

urn:1C.ru:commerceml_2

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

Для решения этой задачи можно использовать один из двух подходов:

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

Посмотрим на пример программной инициализации фабрики XDTO из макета схемы:


// Создаем чтение схемы из макета конфигурации
Схема = Новый СхемаXML;
Схема.РасположениеСхемы = "urn:1C.ru:commerceml_2";

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(ПолучитьМакет("СхемаCommerceML210").ПолучитьТекст());
Схема.ИсходныйТекст = ЧтениеXML;

// Формируем отдельную фабрику XDTO
МояФабрикаXDTO = СоздатьФабрикуXDTO(Схема);

Особенности структуры XDTO-объекта «Группы» в CommerceML

Частая ошибка при попытке наполнить классификатор группами — непонимание внутренней структуры типов схемы CommerceML. В схеме узел <Классификатор> содержит элемент <Группы>, который, в свою очередь, является списком элементов <Группа>.

Если разработчик пытается вызвать метод добавления напрямую у контейнера Классификатор.Группы.Добавить(...) или присвоить туда стандартный ValueListType, платформа возвращает ошибки Значение не является значением объектного типа или Несоответствие типов XDTO. Это происходит потому, что свойство Группы представляет собой сложный тип, содержащий коллекцию Группа.

Разберем по шагам правильный алгоритм создания узлов:

  1. Определяем тип классификатора и создаем сам объект классификатора.
  2. Инициализируем контейнер Группы, создав соответствующий тип XDTO.
  3. Создаем отдельный объект с типом Группа и заполняем его свойства (Ид, Наименование).
  4. Добавляем созданную группу в коллекцию родителя, обращаясь через путь Классификатор.Группы.Группа.Добавить(Группа).

Посмотрим на рабочий пример кода:


URI = "urn:1C.ru:commerceml_2";

// 1. Создание классификатора
ТипКлассификатор = ФабрикаXDTO.Тип(URI, "Классификатор");
Классификатор = ФабрикаXDTO.Создать(ТипКлассификатор);

// 2. Инициализация контейнера групп в классификаторе
ТипГруппы = ФабрикаXDTO.Тип(URI, "Группы");
Классификатор.Группы = ФабрикаXDTO.Создать(ТипГруппы);

// 3. Создание элемента "Группа"
ТипГруппа = ФабрикаXDTO.Тип(URI, "Группа");
НоваяГруппа = ФабрикаXDTO.Создать(ТипГруппа);
НоваяГруппа.Ид = Строка(Новый УникальныйИдентификатор);
НоваяГруппа.Наименование = "Бытовая техника";

// 4. Добавление в коллекцию групп
Классификатор.Группы.Группа.Добавить(НоваяГруппа);

Построение многоуровневой иерархии (вложенные подгруппы)

В стандарте CommerceML иерархия каталога рекурсивна: каждый элемент типа Группа может содержать собственный вложенный контейнер Группы. Если перед добавлением дочерней категории контейнер не проинициализирован, обращение к нему вызовет ошибку обращения к значению Неопределено.

Разберем пример создания родительской группы и добавления в нее дочерней подгруппы:


// Создаем родительскую категорию верхнего уровня
РодительскаяГруппа = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(URI, "Группа"));
РодительскаяГруппа.Ид = "00000001-0000-0000-0000-000000000001";
РодительскаяГруппа.Наименование = "Компьютеры и ноутбуки";

// Инициализируем контейнер для вложенных подгрупп у родителя
РодительскаяГруппа.Группы = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(URI, "Группы"));

// Создаем дочернюю подгруппу
Подгруппа = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(URI, "Группа"));
Подгруппа.Ид = "00000001-0000-0000-0000-000000000002";
Подгруппа.Наименование = "Комплектующие";

// Добавляем дочернюю группу во вложенный список родителя
РодительскаяГруппа.Группы.Группа.Добавить(Подгруппа);

// Добавляем родительскую группу в корень классификатора
Классификатор.Группы.Группа.Добавить(РодительскаяГруппа);

Оптимизация производительности при выгрузке больших каталогов

Выясним причину возможных проблем с быстродействием при формировании каталога. Построение полного XML-дерева товаров и предложений через создание объектов ФабрикаXDTO целиком в оперативной памяти требует значительных ресурсов. На базах с номенклатурой в десятки и сотни тысяч позиций это приводит к ошибкам нехватки памяти (Out of memory).

Для высоконагруженных обменов рекомендуется использовать альтернативные подходы:

  1. Потоковая запись через ЗаписьXML: последовательное формирование файла методами ЗаписатьНачалоЭлемента(), ЗаписатьАтрибут(), ЗаписатьКонецЭлемента(). Память освобождается мгновенно по мере записи узлов в поток.
  2. Комбинированный метод: основной каркас документа создается потоково через ЗаписьXML, а сложные структуры (например, отдельный товар или свойство) генерируются через ФабрикаXDTO и сразу сбрасываются в поток методом ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектXDTO).
  3. Использование готовых модулей интеграции: для типовой конфигурации «Управление торговлей 10.3» разработчики CMS предоставляют готовые внешние модули и обработки обмена, в которых уже реализована поддержка версий CommerceML 2.10 и оптимизирована работа с памятью.
← На главную