Как правильно выгрузить остатки по складам в формате CommerceML 2.08/2.10 и устранить ошибки ЗаписьXML

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

При ручном формировании XML-файлов коммерческих предложений и остатков в формате CommerceML (CML 2.08 / 2.10) разработчики 1С часто сталкиваются с двумя проблемами: некорректным заданием пространств имен через объект ЗаписьXML и непониманием того, где в структуре XML связываются номенклатура, характеристики и остатки по складам.

В этой статье мы подробно разберем структуру пакета предложений CommerceML, выясним, как правильно сопоставлять товары и склады, а также проанализируем ошибки работы с методом ЗаписатьСоответствиеПространстваИмен.

Структура выгрузки остатков в CommerceML

Разберем устройство узла Предложение в стандарте CML. Ошибка начинающих разработчиков заключается в поиске отдельных элементов Номенклатура или Характеристика внутри узла остатков. В стандарте CommerceML товар и его характеристика идентифицируются строкой Ид самого предложения:

  1. Если выгружается номенклатура без характеристик: в узле Ид указывается только GUID номенклатуры.
  2. Если выгружается номенклатура с характеристикой: в узле Ид задается составной идентификатор через разделитель # в формате GUID_номенклатуры#GUID_характеристики.

Склады и количества товаров располагаются внутри узла Предложение в блоке Остатки. Посмотрим на пример корректной XML-структуры:


<КоммерческаяИнформация xmlns="urn:1C.ru:commerceml_2" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ВерсияСхемы="2.10" ДатаФормирования="2023-10-15T12:00:00" Ид="1">
    <ПакетПредложений СодержитТолькоИзменения="true">
        <Ид>60a46932-84a0-4f8c-900f-91c73525d281#</Ид>
        <Наименование>Пакет предложений</Наименование>
        <ИдКаталога>60a46932-84a0-4f8c-900f-91c73525d281</ИдКаталога>
        <ИдКлассификатора>60a46932-84a0-4f8c-900f-91c73525d281</ИдКлассификатора>
        <Предложения>
            <Предложение>
                <Ид>9d077c0e-0c65-11e6-812a-002590da294c#11111111-0c65-11e6-812a-002590da294c</Ид>
                <Наименование>Товар 1 (Характеристика 1)</Наименование>
                <Остатки>
                    <Остаток>
                        <Склад>
                            <Ид>31d21b45-f4fb-11e5-812a-002590da294c</Ид>
                            <Количество>4</Количество>
                        </Склад>
                    </Остаток>
                </Остатки>
            </Предложение>
        </Предложения>
    </ПакетПредложений>
</КоммерческаяИнформация>

Причины ошибок при объявлении пространств имен в ЗаписьXML

При программном формировании файла через объект ЗаписьXML часто возникает ошибка вида: «Ошибка установки соответствия префикса и URI пространства имен». Выясним причину ее возникновения.

Рассмотрим ошибочные вызовы:


// Ошибка 1: передача "xmlns" в качестве префикса
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xmlns", "urn:1C.ru:commerceml_2");

// Ошибка 2: передача "xmlns:xs" в качестве префикса
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xmlns:xs", "http://www.w3.org/2001/XMLSchema");

Правила работы метода ЗаписатьСоответствиеПространстваИмен требуют передавать только имя префикса без служебного ключевого слова XML xmlns:

  1. Для пространства имен по умолчанию (без префикса): в качестве первого параметра передается пустая строка "".
  2. Для именованных префиксов (например, xs или xsi): передается только имя префикса без двоеточия и слова xmlns.

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


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\export\offers.xml", "UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();

// Открываем корневой элемент
ЗаписьXML.ЗаписатьНачалоЭлемента("КоммерческаяИнформация");

// Регистрируем пространство имен по умолчанию (xmlns="...")
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("", "urn:1C.ru:commerceml_2");

// Регистрируем дополнительные префиксы (xmlns:xs="..." и xmlns:xsi="...")
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xs", "http://www.w3.org/2001/XMLSchema");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");

// Записываем прочие атрибуты корневого узла
ЗаписьXML.ЗаписатьАтрибут("ВерсияСхемы", "2.10");
ЗаписьXML.ЗаписатьАтрибут("ДатаФормирования", Формат(ТекущаяДата(), "ДФ=yyyy-MM-ddTHH:mm:ss"));
ЗаписьXML.ЗаписатьАтрибут("Ид", "1");

Альтернативный и еще более простой способ — указывать URI пространства имен напрямую при вызове метода ЗаписатьНачалоЭлемента. В этом случае платформа 1С автоматически добавит пространство имен по умолчанию:


ЗаписьXML.ЗаписатьНачалоЭлемента("КоммерческаяИнформация", "urn:1C.ru:commerceml_2");
ЗаписьXML.ЗаписатьАтрибут("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
ЗаписьXML.ЗаписатьАтрибут("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

Альтернативное решение: использование XDTO

Чтобы избежать ошибки ручного синтаксиса XML и контролировать строгое соответствие схеме CML, рекомендуется использовать механизмы XDTO. При загрузке XDTO-пакета CommerceML в конфигурацию формирование документа сведе́тся к заполнению свойств объектов и вызову ЗаписьXDTO.Записать(). В этом случае платформа автоматически сформирует заголовок, установит корректные пространства имен и проверит последовательность узлов.

← На главную