Как правильно настроить генерацию XML через XDTO для ЕГАИС в 1С: решаем проблемы с префиксами и пространствами имен

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

Работа с механизмом XDTO (XML Data Transfer Objects) в 1С часто вызывает трудности у разработчиков, особенно при первой встрече. Одной из наиболее сложных задач является формирование строго определенной структуры XML, соответствующей требованиям внешних систем, таких как ЕГАИС (УТМ). Основные проблемы обычно связаны с «лишними» префиксами, дублированием пространств имен в дочерних узлах и невозможностью стандартными средствами задать специфические атрибуты в заголовке XML (например, standalone="no").

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

Разбор проблемы: почему XDTO генерирует «лишние» данные

Рассмотрим ситуацию, когда при использовании метода ФабрикаXDTO.ЗаписатьXML() в дочерних тегах (например, Owner или Document) начинают дублироваться объявления пространств имен (атрибуты xmlns). Это происходит потому, что разработчик зачастую вызывает метод записи отдельно для каждой части объекта. Когда ФабрикаXDTO записывает отдельный фрагмент, она не «знает», что этот фрагмент будет вставлен внутрь другого XML-документа, где пространство имен уже объявлено. Чтобы фрагмент оставался валидным сам по себе, система принудительно вставляет в него описание xmlns.

Также часто возникает вопрос с префиксами (например, ns:). Если в схеме XSD указано свойство elementFormDefault="qualified", 1С будет настойчиво добавлять префикс ко всем элементам. Если же нам нужно, чтобы дочерние элементы шли без префиксов, или наоборот — строго с ними, требуется тонкая настройка объекта ЗаписьXML.

Способ 1: Тонкая настройка Записи XML и единый вызов Фабрики

Чтобы избежать дублирования пространств имен и контролировать префиксы, мы должны следовать правилу: записывать весь объект целиком одним вызовом, предварительно настроив сопоставление пространств имен. Разберем этот процесс по шагам.

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


// Подготовка записи
ЗаписьXML = Новый ЗаписьXML;
ПараметрыЗаписиXML = Новый ПараметрыЗаписиXML("UTF-8", "1.0", Истина, Истина);
ЗаписьXML.УстановитьСтроку(ПараметрыЗаписиXML);

// 1. Ручная запись заголовка с атрибутом standalone
// Поскольку стандартные параметры записи 1С не поддерживают standalone, 
// используем запись без обработки
ЗаписьXML.ЗаписатьБезОбработки("<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>" + Символы.ПС);

// 2. Настройка пространств имен
// Мы явно связываем префикс "ns" с нужным URI
// Если нужно, чтобы основное пространство было без префикса, передаем пустую строку ""
ЗаписьXML.ЗаписатьНачалоЭлемента("ns", "Documents", "http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("ns", "http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("pref", "http://fsrar.ru/WEGAIS/QueryFilter");
ЗаписьXML.ЗаписатьАтрибут("Version", "1.0");

// 3. Запись вложенных данных
// Вместо того чтобы записывать Owner и Document отдельно, 
// мы передаем объект целиком в Фабрику
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектXDTO.Owner, "Owner", "http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01");
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектXDTO.Document, "Document", "http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01");

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

Обратите внимание: если мы хотим, чтобы 1С не добавляла префиксы к дочерним узлам, в методе ЗаписатьСоответствиеПространстваИмен в качестве первого параметра (префикса) нужно передать пустую строку. Это сделает данное пространство имен «дефолтным» для текущего узла и всех вложенных в него элементов.

Способ 2: Использование шаблонов строк (Дедовский метод)

Как показывает практика интеграции с ЕГАИС, требования УТМ к формату XML бывают настолько жесткими, что использование ФабрикаXDTO становится избыточным или слишком сложным в отладке. В таких случаях многие разработчики переходят на формирование XML через текстовые шаблоны. Это гарантирует, что в файле не будет ни одного лишнего пробела или атрибута, который 1С могла бы вставить автоматически.

Рассмотрим пример формирования запроса на остатки марок, где используется простая замена параметров в строке-шаблоне:


Функция СоздатьЗапросНаОстатокМарок(РарИД, ИдентификаторФормы) Экспорт
    
    ШаблонXML = 
    "<?xml version=""1.0"" encoding=""UTF-8""?>
    |<ns:Documents Version=""1.0""
    |    xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
    |    xmlns:ns=""http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01""
    |    xmlns:qp=""http://fsrar.ru/WEGAIS/QueryParameters"">
    |    <ns:Owner>
    |        <ns:FSRAR_ID>[Параметр_РарИД]</ns:FSRAR_ID>
    |    </ns:Owner>
    |    <ns:Document>
    |        <ns:QueryRestBCode>
    |            <qp:Parameters>
    |                <qp:Parameter>
    |                    <qp:Name>ФОРМА2</qp:Name>
    |                    <qp:Value>[Параметр_ФормаИД]</qp:Value>
    |                </qp:Parameter>
    |            </qp:Parameters>
    |        </ns:QueryRestBCode>
    |    </ns:Document>
    |</ns:Documents>";
    
    ТекстЗапроса = СтрЗаменить(ШаблонXML, "[Параметр_РарИД]", РарИД);
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[Параметр_ФормаИД]", ИдентификаторФормы);
    
    Возврат ТекстЗапроса;
    
КонецФункции

Хотя этот метод кажется менее «технологичным», он лишен проблем с автоматической генерацией префиксов 1С. Однако у него есть существенный минус: если структура документа сложная (например, содержит список из 1000 марок), ручная сборка строки становится трудоемкой и подверженной ошибкам. В этом случае лучше вернуться к XDTO, но использовать его правильно.

Как убрать префикс ns в конкретных узлах

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

Рассмотрим пример:

  1. Открываем корневой элемент с префиксом ns.
  2. Внутри него вызываем ЗаписатьСоответствиеПространстваИмен("", "URI_Пространства").
  3. После этого все элементы, записываемые ФабрикойXDTO, будут считаться принадлежащими этому пространству имен, но префикс к ним добавляться не будет, так как мы указали пустую строку в качестве префикса по умолчанию.

Важные нюансы при работе с ЕГАИС

При работе с ФабрикаXDTO для ЕГАИС следует учитывать еще несколько критических моментов:

Резюме

Для создания идеального XML-документа через XDTO мы рекомендуем комбинированный подход: используйте ЗаписьXML для формирования «шапки» документа и управления пространствами имен, а ФабрикаXDTO — для наполнения документа данными. Это позволит сохранить строгий порядок тегов и типизацию, избежав при этом мусора в виде лишних префиксов и повторяющихся объявлений xmlns.

Если же структура документа крайне проста, а требования к оформлению специфичны, использование текстовых шаблонов или DOM (Document Object Model) может оказаться более быстрым и надежным решением.

← На главную