Как в 1С записать XML с нужными атрибутами корневого элемента без лишних пространств имен?

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

При интеграции 1С со сторонними системами (например, ПО «Альта-ГТД», сервисами ЭД-2 или иными таможенными шлюзами) разработчики часто сталкиваются со строгими требованиями к формату XML. Нередко внешний сервис ожидает увидеть корневой тег с фиксированным набором атрибутов и категорически не принимает стандартные объявления пространств имен (такие как xmlns:xs, xmlns:xsi или схему xmlns).

Если для формирования файла используется фабрика XDTO (ФабрикаXDTO.ЗаписатьXML), платформа принудительно прописывает пространства имен пакета и W3C-схем в открывающем теге. Выясним причину такого поведения и подробно разберем практические способы решения этой задачи.

Почему ФабрикаXDTO добавляет лишние пространства имен

Проанализируем механику работы механизма XDTO. Метод ФабрикаXDTO.ЗаписатьXML ориентирован на создание строго валидного XML по стандартам W3C. Если в пакете задан targetNamespace, платформа всегда декларирует его в корневом узле вместе со служебными пространствами xmlns:xs="http://www.w3.org/2001/XMLSchema" и xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance".

В платформе 1С не предусмотрено штатных параметров в методе ЗаписатьXML, которые отключали бы генерацию этих деклараций. Кроме того, если в XSD-схеме корневой элемент или его тип являются анонимными, фабрика может не сопоставить атрибуты верхнего уровня, из-за чего параметры вроде time, user или FileName вообще не попадут в открывающий тег. Для обхода этих ограничений применяются несколько рабочих подходов.

Способ 1. Прямая запись корневого узла через объект ЗаписьXML

Самое быстрое и надежное решение для обхода жестких ограничений XDTO — сформировать открывающий тег корневого элемента и его атрибуты вручную с помощью объекта ЗаписьXML.

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


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

// Формируем корневой узел с нужными атрибутами
Запись.ЗаписатьНачалоЭлемента("AltaINV");
Запись.ЗаписатьАтрибут("time", "2025-09-19T16:05:12+03:00");
Запись.ЗаписатьАтрибут("user", "DES");
Запись.ЗаписатьАтрибут("Version", "2.0.261.9");
Запись.ЗаписатьАтрибут("FileName", "*{8FA2CC3F-3041-4657-8C2B-D2E02C5E7C1B}\{63EE63B9-B7B0-4F5E-8AC4-7C6B5CC876C6}.INV");
Запись.ЗаписатьАтрибут("EDVer", "5_25_0");
Запись.ЗаписатьАтрибут("Comment", "");

// Здесь выполняется запись дочерних элементов или тела документа

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

Такой подход полностью исключает автоматическое внедрение пространств имен в корневой тег и гарантирует, что файл начнется строго в том виде, который ожидает парсер принимающей системы.

Способ 2. Комбинированный подход: ручной корень и вложенные объекты XDTO

Разберем по шагам ситуацию, когда документ содержит сложную и глубокую структуру вложенных данных, которую нерационально переписывать вручную. В этом случае корень формируется через ЗаписьXML, а сложное содержимое — через вызовы фабрики XDTO.

  1. Открываем файл через ЗаписьXML и создаем объявление XML с нужной кодировкой.
  2. Методом ЗаписатьНачалоЭлемента открываем корневой тег и добавляем атрибуты через ЗаписатьАтрибут.
  3. Для записи каждого дочернего XDTO-объекта вызываем метод ФабрикаXDTO.ЗаписатьXML, передавая в параметре НазначениеТипаXML значение НазначениеТипаXML.Неявное. Это предотвратит генерацию лишних типов xsi:type во вложенных узлах.
  4. Закрываем корневой элемент вызовом ЗаписатьКонецЭлемента и закрываем файл.

Посмотрим на пример реализации комбинированного подхода:


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

Запись.ЗаписатьНачалоЭлемента("AltaINV");
Запись.ЗаписатьАтрибут("time", Формат(ТекущаяДатаСеанса(), "ДФ=yyyy-MM-ddTHH:mm:ss+03:00"));
Запись.ЗаписатьАтрибут("user", "DES");
Запись.ЗаписатьАтрибут("Version", "2.0.261.9");

// Выгрузка вложенного объекта XDTO в поток ЗаписьXML
ФабрикаXDTO.ЗаписатьXML(Запись, ДочернийОбъектXDTO, , , НазначениеТипаXML.Неявное);

Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();

Способ 3. Модификация документа через DOM

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

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

  1. Выгружаем данные из XDTO или строки в дерево DOM с помощью объекта ПостроительDOM.
  2. Получаем доступ к корневому узлу через свойство ДокументDOM.ЭлементДокумента.
  3. Удаляем нежелательные атрибуты пространств имен методом УдалитьАтрибут() (например, xmlns:xs, xmlns:xsi).
  4. Устанавливаем необходимые реквизиты с помощью метода УстановитьАтрибут().
  5. Записываем очищенный ДокументDOM в целевой файл через объект ЗаписьDOM и настроенный ЗаписьXML. При сериализации через ЗаписьDOM платформа не добавляет сторонние пространства имен самостоятельно.

Выбор конкретного метода зависит от архитектуры обмена: для простых пакетов и передачи файлов в сторонние утилиты оптимален Способ 1, а при работе с большими схемами XSD максимальное удобство обеспечивает комбинированный вариант.

← На главную