При выгрузке данных в формат XML с использованием объектов XDTO разработчики часто сталкиваются с ситуацией, когда платформа 1С автоматически генерирует системные префиксы пространств имен вида d1p1, d3p1, d5p1 или дублирует объявления xmlns внутри каждого дочернего тега. Это может приводить к ошибкам валидации документа внешней XSD-схемой и затрудняет интеграцию с государственными или корпоративными сервисами.
Разберем подробнее, почему возникает такое поведение платформы, как корректно управлять префиксами и как правильно организовать запись XML с помощью Фабрики XDTO.
В свойствах самого объекта метаданных XDTO-пакет нельзя жестко зафиксировать пользовательский префикс. Если объект ЗаписьXML не содержит предварительно объявленных соответствий «префикс — URI пространства имен», сериализатор 1С назначает собственные префиксы по шаблону d<N>p1 по мере обнаружения новых пространств имен в дереве типов.
Если же попытаться вызвать метод ЗаписьXML.ЗаписатьСоответствиеПространстваИмен() непосредственно перед вызовом ФабрикаXDTO.ЗаписатьXML() без предварительного открытия корневого элемента или после него, платформа выдает исключение "Ошибочный порядок записи XML". Это происходит потому, что пространство имен может быть зарегистрировано только в момент открытия элемента до записи его содержимого или атрибутов.
Проанализируем правильный алгоритм решения задачи. Чтобы задать нужные префиксы и избежать дублирования атрибутов xmlns в дочерних узлах, сформируем корневой элемент документа вручную с помощью методов объекта ЗаписьXML, зарегистрируем все необходимые пространства имен, а затем сериализуем вложенные данные фабрикой.
Разберем по шагам реализацию на примере кода:
ЗаписьXML и инициализируем вывод (в строку или файл).ЗаписатьНачалоЭлемента().ЗаписатьСоответствиеПространстваИмен().ФабрикаXDTO.ЗаписатьXML().ЗаписатьКонецЭлемента() и завершим запись.Посмотрим на практический пример кода 1С:
ЗаписьХМЛ = Новый ЗаписьXML;
ЗаписьХМЛ.УстановитьСтроку();
ЗаписьХМЛ.ЗаписатьОбъявлениеXML();
URI_Главное = "http://dol.minstroyrf.ru/v1.2/eqconcom.xsd";
URI_Служебное = "http://www.w3.org/2001/XMLSchema-instance";
// Открываем корневой элемент документа
ЗаписьХМЛ.ЗаписатьНачалоЭлемента("Chief", URI_Главное);
// Регистрируем желаемые префиксы пространств имен
ЗаписьХМЛ.ЗаписатьСоответствиеПространстваИмен("con", URI_Главное);
ЗаписьХМЛ.ЗаписатьСоответствиеПространстваИмен("xsi", URI_Служебное);
// Записываем тело объекта через ФабрикуXDTO
// Обязательно передаем пространство имен элемента
ФабрикаXDTO.ЗаписатьXML(ЗаписьХМЛ, Объект_Declaration, "Chief", URI_Главное);
// Закрываем корневой элемент
ЗаписьХМЛ.ЗаписатьКонецЭлемента();
РезультатXML = ЗаписьХМЛ.Закрыть();
Рассмотрим дополнительные параметры метода ФабрикаXDTO.ЗаписатьXML(), которые позволяют получить корректный XML-документ, проходящий валидацию:
ФабрикаXDTO.ЗаписатьXML() принимает параметр <УказаниеТипа>. Если схема валидации запрещает явное указание типа через атрибут xsi:type, укажем значение НазначениеТипаXML.Неявное.xmlns="..." внутри каждого вложенного тега.elementFormDefault в XSD-схеме. Если в схеме установлено unqualified, дочерние элементы должны идти без префиксов, а при значении qualified — обязательно содержать префикс целевого пространства.Если внешняя система предъявляет нестандартные требования к форматированию XML-документа, рассмотрим альтернативные механизмы платформы 1С:
ДокументDOM и ЗаписьDOM можно программно выстроить дерево XML, детально управляя свойствами Префикс, ПространствоИменURI и методами установки атрибутов с учетом пространств имен (УстановитьАтрибутNS).ПреобразованиеXSL. Это позволяет очистить документ от лишних префиксов или переименовать их по жестко заданному шаблону перед отправкой.