Как добавить пространства имен xmlns:xsi и атрибут xsi:schemaLocation в XML-файл в 1С

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

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


<kaspi_catalog date="string"
               xmlns="kaspiShopping"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="kaspiShopping http://kaspi.kz/kaspishopping.xsd">
</kaspi_catalog>

Попытки прописать эти параметры "в лоб" стандартными методами часто приводят к невалидной XML-структуре. Давайте подробно разберем типичные ошибки разработчиков 1С при работе с пространствами имен, выясним их причины и рассмотрим три надежных способа правильного решения этой задачи: через последовательную запись XML, с помощью объектной модели DOM и с использованием механизмов XDTO.

Анализ типичной ошибки: почему не работает простой способ?

Рассмотрим код, который часто пытаются использовать разработчики на начальном этапе решения задачи:


ЗаписьXMl.ЗаписатьНачалоЭлемента("kaspi_catalog");
ЗаписьXMl.ЗаписатьАтрибут("date", "", "string");
ЗаписьXMl.ЗаписатьАтрибут("xmlns", "", "kaspiShopping");

ЗаписьXMl.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
ЗаписьXMl.ЗаписатьСоответствиеПространстваИмен("schemaLocation", "kaspiShopping http://kaspi.kz/kaspishopping.xsd");

При выполнении такого кода платформа 1С сгенерирует некорректный XML-тег:


<kaspi_catalog xmlns:schemaLocation="kaspiShopping http://kaspi.kz/kaspishopping.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" date="string" xmlns="kaspiShopping">

Выясним причину этой ошибки. Метод ЗаписатьСоответствиеПространстваИмен предназначен исключительно для связывания короткого префикса (например, xsi или xsd) с его уникальным URI-адресом. Платформа 1С воспринимает первый параметр этого метода как префикс пространства имен. Объявив строку "schemaLocation" в качестве префикса, мы заставили систему сгенерировать объявление нового пространства имен с именем xmlns:schemaLocation="...". На самом же деле, schemaLocation — это не префикс, а обычный XML-атрибут, принадлежащий пространству имен http://www.w3.org/2001/XMLSchema-instance.

Решение №1: Правильное использование ЗаписьXML

Объект ЗаписьXML является быстрым и эффективным средством для записи XML "на лету" без загрузки всего документа в оперативную память. Чтобы получить валидную структуру с помощью этого объекта, мы должны выполнить несколько последовательных шагов:

  1. Открыть корневой элемент, сразу сопоставив его с пространством имен по умолчанию (в нашем примере это "kaspiShopping").
  2. Записать обычные текстовые атрибуты (например, date).
  3. Зарегистрировать префикс xsi для пространства имен XML-схем.
  4. Записать атрибут schemaLocation, явно указав его принадлежность к пространству имен xsi.

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


// Создаем объект записи и открываем файл
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\kaspi_catalog.xml", "UTF-8");

// Шаг 1. Открываем корневой элемент. 
// Второй параметр указывает пространство имен по умолчанию (xmlns="kaspiShopping")
ЗаписьXML.ЗаписатьНачалоЭлемента("kaspi_catalog", "kaspiShopping");

// Шаг 2. Записываем стандартный атрибут "date"
ЗаписьXML.ЗаписатьАтрибут("date", "string");

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

// Шаг 4. Записываем атрибут "schemaLocation"
// Указываем локальное имя атрибута, URI пространства имен и его значение.
// Платформа определит, что данный URI связан с префиксом "xsi", и автоматически запишет его как "xsi:schemaLocation"
ЗаписьXML.ЗаписатьАтрибут("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance", "kaspiShopping http://kaspi.kz/kaspishopping.xsd");

// Закрываем элемент и завершаем запись
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();

Этот способ является максимально производительным, так как запись происходит последовательно в поток. Он идеально подходит для формирования файлов большого объема.

Решение №2: Использование Объектной Модели DOM

Если структура файла сложная, динамическая или вам требуется изменять уже существующий XML-документ, последовательная запись потоком может быть неудобной. В таких случаях мы рекомендуем использовать объектную модель документа (DOM) с помощью объектов ДокументDOM и ЭлементDOM. Здесь для установки атрибутов используется метод УстановитьАтрибут, который позволяет гибко управлять пространствами имен.

Рассмотрим по шагам, как построить аналогичный заголовок через DOM:


// Создаем новый DOM-документ
ДокументDOM = Новый ДокументDOM;

// Шаг 1. Создаем корневой элемент в пространстве имен "kaspiShopping"
// Используем метод СоздатьЭлементИП для поддержки пространств имен
КорневойЭлемент = ДокументDOM.СоздатьЭлементИП("kaspiShopping", "kaspi_catalog");
ДокументDOM.ДобавитьДочерний(КорневойЭлемент);

// Шаг 2. Устанавливаем простой атрибут "date"
КорневойЭлемент.УстановитьАтрибут("date", "string");

// Шаг 3. Устанавливаем объявление пространства имен "xmlns:xsi"
// По стандартам W3C, префиксы xmlns объявляются в специальном пространстве имен "http://www.w3.org/2000/xmlns/"
КорневойЭлемент.УстановитьАтрибут("http://www.w3.org/2000/xmlns/", "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

// Шаг 4. Устанавливаем атрибут "xsi:schemaLocation"
// Передаем URI пространства имен xsi, имя атрибута с префиксом и значение
КорневойЭлемент.УстановитьАтрибут("http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation", "kaspiShopping http://kaspi.kz/kaspishopping.xsd");

// Записываем DOM-документ в файл
ЗаписьDOM = Новый ЗаписьDOM;
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\kaspi_catalog_dom.xml", "UTF-8");
ЗаписьDOM.Записать(ДокументDOM, ЗаписьXML);
ЗаписьXML.Закрыть();

Использование DOM требует больше оперативной памяти, но исключает ошибки ручной работы со строками и префиксами, гарантируя строгое соответствие стандартам XML.

Решение №3: Профессиональный подход с использованием XDTO

В промышленной разработке ручное формирование тегов и атрибутов считается не лучшей практикой. Если у принимающей стороны есть готовая схема валидации (файл с расширением .xsd), то самым правильным и надежным решением будет использование встроенного в 1С механизма XDTO (XML Data Transfer Objects). Для быстрой подготовки схем можно использовать инструмент для формирования XSD-пакета для загрузки в XDTO.

Давайте разберем алгоритм работы через XDTO:

  1. Скачайте XSD-схему от интегратора (например, с сайта Kaspi).
  2. Импортируйте её в конфигурацию 1С как Пакет XDTO (в ветке метаданных "Общие -> Пакеты XDTO").
  3. В программном коде используйте объект ФабрикаXDTO для создания объектов по схемам пакета.

Пример программного кода для генерации XML через XDTO:


// 1. Инициализируем запись XML
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\kaspi_catalog_xdto.xml", "UTF-8");

// 2. Определяем пространство имен нашего XDTO-пакета
ПространствоИменКаталога = "kaspiShopping";

// 3. Создаем объект каталога по типу, описанному в пакете XDTO
ТипКаталога = ФабрикаXDTO.Тип(ПространствоИменКаталога, "kaspi_catalog");
КаталогXDTO = ФабрикаXDTO.Создать(ТипКаталога);

// 4. Заполняем свойства объекта (атрибуты и дочерние элементы)
КаталогXDTO.date = "string";

// 5. Записываем готовый объект в файл через Фабрику XDTO
// Платформа 1С автоматически сформирует все необходимые объявления пространств имен
// и проставит префиксы "xsi" и атрибуты "xsi:schemaLocation" в строгом соответствии с XSD-схемой
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, КаталогXDTO);
ЗаписьXML.Закрыть();

Преимущество XDTO заключается в том, что вам вообще не нужно думать о синтаксисе XML, кавычках, префиксах и пространствах имен. Платформа делает всю рутинную работу автоматически, гарантируя 100% валидность файла для принимающего парсера.

Влияет ли порядок следования атрибутов на загрузку файла?

Иногда разработчики переживают, что после автоматической генерации XML-файла средствами 1С порядок атрибутов внутри тега отличается от примера в документации интегратора. Например, в примере указано: date, затем xmlns, затем xsi:schemaLocation, а 1С записывает сначала пространства имен, а затем date.

Давайте проанализируем стандарты консорциума W3C. Согласно официальной спецификации XML, атрибуты внутри любого тега представляют собой неупорядоченное множество (коллекцию пар "ключ-значение"). Любой корректно написанный XML-парсер считывает атрибуты в ассоциативный массив, где порядок их следования абсолютно не важен.

Таким образом, конструкции:


<kaspi_catalog date="string" xmlns="kaspiShopping" xmlns:xsi="..." xsi:schemaLocation="...">

и


<kaspi_catalog xmlns="kaspiShopping" xmlns:xsi="..." xsi:schemaLocation="..." date="string">

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

Резюме

Для надежного добавления пространств имен и атрибутов схемы в XML-файл в 1С избегайте ручной склейки текстовых строк. Используйте метод ЗаписатьАтрибут с указанием URI пространства имен при работе с ЗаписьXML, метод УстановитьАтрибут при использовании DOM, либо внедряйте механизм XDTO для автоматического контроля структуры по XSD-схемам.

← На главную