Как убрать автоматические префиксы пространств имен d3p1 при записи XML в 1С

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

При интеграции 1С с внешними системами через протоколы обмена данными (например, SOAP или REST) программисты часто сталкиваются с особенностью работы объекта ЗаписьXML. Платформа 1С при указании пространства имен автоматически генерирует префиксы вида d3p1, d3p2 и так далее. Несмотря на то что с точки зрения стандартов XML наличие префикса не является ошибкой (если он корректно сопоставлен с URI), многие принимающие системы или упрощенные парсеры отказываются обрабатывать такие сообщения, требуя «чистые» теги без префиксов.

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

Почему 1С добавляет префиксы d3p1?

Рассмотрим ситуацию: вы используете метод ЗаписатьНачалоЭлемента и передаете в него два параметра: имя тега и URI пространства имен. Например:

ЗаписьXML.ЗаписатьНачалоЭлемента("transfer", "http://ttt.com/ttt");

Для платформы 1С это сигнал о том, что элемент transfer принадлежит указанному пространству имен. Однако, если ранее в документе не было объявлено соответствие этого URI какому-либо префиксу (включая пустой префикс по умолчанию), система вынуждена создать технический префикс самостоятельно, чтобы гарантировать валидность документа. Так в вашем XML появляется запись вида <d3p1:transfer xmlns:d3p1="http://ttt.com/ttt">.

Проанализируем ситуацию подробнее. С точки зрения спецификации XML Namespaces, запись без префикса возможна только тогда, когда пространство имен объявлено как default namespace (через атрибут xmlns без двоеточия). Выясним, как заставить 1С генерировать именно такой формат.

Способ 1. Использование метода ЗаписатьСоответствиеПространстваИмен

Это самый правильный и надежный способ управления префиксами. Мы можем явно указать системе, что для конкретного URI должен использоваться «пустой» префикс. Разберем по шагам, как это реализовать.

Во-первых, необходимо создать корневой элемент или родительский узел, в котором будет объявлено пространство имен. Во-вторых, нужно использовать метод ЗаписатьСоответствиеПространстваИмен, передав в качестве первого параметра пустую строку.


// Создаем объект записи
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

// Записываем начало корневого элемента (пока без URI)
ЗаписьXML.ЗаписатьНачалоЭлемента("root");

// Объявляем пространство имен по умолчанию (пустой префикс)
// Первый параметр - пустая строка, второй - ваш URI
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("", "http://www.ttt.com/ttt");

// Теперь записываем вложенный элемент, указывая тот же URI
// 1С увидит, что для этого URI уже назначен пустой префикс, и не будет создавать d3p1
ЗаписьXML.ЗаписатьНачалоЭлемента("transfer", "http://www.ttt.com/ttt");
ЗаписьXML.ЗаписатьАтрибут("version", "01.05.00");
ЗаписьXML.ЗаписатьКонецЭлемента(); // закрываем transfer

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

Результат = ЗаписьXML.Закрыть();

В результате мы получим структуру, где элемент transfer будет записан без лишних букв в имени тега, так как он наследует пространство имен по умолчанию от родителя или объявляет его сам.

Способ 2. Принудительная установка префикса через УстановитьПрефикс

Если структура XML сложная и вам нужно гарантировать отсутствие префиксов для определенных пространств на протяжении всей записи, воспользуемся методом УстановитьПрефикс. Рассмотрим пример:


ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл("C:\temp\request.xml");

// Устанавливаем соответствие ПЕРЕД записью элементов
ЗаписьXML.УстановитьПрефикс("", "http://www.ttt.com/ttt");

// Теперь при записи элемента с этим URI префикс d3p1 не появится
ЗаписьXML.ЗаписатьНачалоЭлемента("transfer", "http://www.ttt.com/ttt");
// ... запись атрибутов ...
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.Закрыть();

Метод УстановитьПрефикс работает как «подсказка» для парсера: всякий раз, когда встречается указанный URI, использовать именно этот префикс (в нашем случае — пустой).

Способ 3. Ручная запись атрибута xmlns (Обходной путь)

Как было отмечено в обсуждении на форуме, существует «хакерский» способ — записать xmlns как обычный атрибут. Посмотрим на пример кода:


// В методе ЗаписатьНачалоЭлемента НЕ указываем URI вторым параметром
ЗаписьXML.ЗаписатьНачалоЭлемента("transfer");

// Записываем пространство имен как обычный текстовый атрибут
ЗаписьXML.ЗаписатьАтрибут("xmlns", "http://www.ttt.com/ttt");
ЗаписьXML.ЗаписатьАтрибут("version", "01.05.00");

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

Важное предостережение: Хотя этот способ часто работает для простых документов, он считается небезопасным. Объект ЗаписьXML может не отследить такое «ручное» объявление. Если внутри этого элемента вы попытаетесь создать дочерние узлы через штатный механизм пространств имен, платформа может создать конфликт имен или продублировать объявления. Используйте этот метод только в самых крайних случаях, когда другие способы не помогают «подружиться» с принимающим веб-сервисом.

Способ 4. Работа через механизмы XDTO

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

  1. Валидация: Данные проверяются на соответствие типам еще до момента записи.
  2. Автоматизация: Если в схеме указано elementFormDefault="qualified", но при этом для корневого пакета настроено отсутствие префиксов, 1С сама сформирует правильный XML.
  3. Удобство: Вы работаете с объектами и свойствами, а не с текстовыми тегами.

Пример записи XDTO в ЗаписьXML без лишних префиксов:


// Предположим, у нас есть объект XDTO 'МойОбъект'
// и ФабрикаXDTO, инициализированная нужной схемой.

ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();

// При сериализации можно управлять настройками пространств имен
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, МойОбъект, , , , НазначениеТипаXML.Явное);

Выводы и рекомендации

Подведем итоги нашего исследования. Если внешняя система «ругается» на префиксы d3p1, выполните следующие действия:

Разбор этих методов показывает, что платформа 1С предоставляет достаточно гибкие инструменты для работы с XML любой сложности. Главное — понимать механику наследования пространств имен и вовремя подсказывать системе, какой префикс вы ожидаете увидеть в итоговом документе.

← На главную