При переходе со старых версий платформы (например, 8.2 или ранних 8.3) на современные релизы программисты часто сталкиваются с тем, что отлаженные механизмы обмена данными через XDTO начинают выдавать ошибки. Одной из самых распространенных является ошибка преобразования данных: Ошибка проверки данных XDTO: Структура объекта не соответствует типу. Особенно остро это проявляется при изменении режима совместимости конфигурации на 8.3.8 и выше.
В данной статье мы подробно разберем, почему это происходит, как платформа 1С изменила подход к проверке XML-пакетов и какие конкретные шаги нужно предпринять, чтобы восстановить работоспособность обмена.
Главная причина кроется в ужесточении контроля соответствия XML-файла схеме XSD, которое произошло в платформе, начиная с версии 8.3.8. До этого момента механизм XDTO в 1С был более лоялен к так называемым «неквалифицированным» элементам. Если в схеме было указано, что элементы не должны иметь префикса пространства имен, а в XML-файле они его имели (или находились в пространстве имен по умолчанию), платформа 8.2 могла «проигнорировать» это несовпадение и успешно прочитать файл.
Начиная с версии 8.3.8, 1С перешла на строгое соответствие стандартам W3C. Рассмотрим ситуацию на примере из сообщения автора темы. Проблема возникает при чтении элемента ДатаВыгрузки, который входит в тип Данные. Система сообщает, что структура объекта не соответствует типу, хотя визуально данные в XML выглядят корректно.
Выясним, что именно не нравится платформе. В схеме XSD (сообщение 11) указано свойство elementFormDefault="unqualified". Это означает следующее:
Однако, если ваш XML-файл начинается с объявления <Данные xmlns="http://www.mycompany.com">, то согласно правилам XML, все вложенные элементы автоматически наследуют это пространство имен. Для новой платформы 1С это означает, что элемент ДатаВыгрузки теперь принадлежит пространству http://www.mycompany.com, в то время как схема (из-за unqualified) ожидает встретить его без пространства имен вообще. Результат — ошибка проверки структуры.
Рассмотрим самый правильный и надежный способ решения проблемы, если у вас есть возможность редактировать XSD-схему или пакет XDTO внутри конфигурации. Нам необходимо явно сказать платформе, что все элементы внутри нашего пространства имен должны быть «квалифицированными» (то есть принадлежать этому пространству).
Для этого выполним следующие действия:
XDTO-пакет в конфигураторе (или отредактируем внешний файл .xsd).<xs:schema>) найдем параметр «Квалифицированная форма элемента» (elementFormDefault).qualified).После этого изменения платформа будет ожидать, что вложенные элементы ДатаВыгрузки, ПериодВыгрузки и другие принадлежат тому же пространству имен, что и корневой элемент. Это полностью устранит конфликт при чтении XML с объявленным xmlns.
Иногда схема приходит из внешней системы, и мы не можем её менять. В этом случае нам нужно правильно инициализировать процесс чтения в коде 1С. Посмотрим на пример кода, который использовал автор для инициализации схемы:
// Создаем набор схем на основе внешнего XSD-файла
НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(ПутьКФайлуСхемы);
// Создаем локальную фабрику XDTO
МояФабрика = Новый ФабрикаXDTO(НаборСхем);
// Используем СериализаторXDTO для связи с типами 1С
Сериализатор = Новый СериализаторXDTO(МояФабрика);
// Открываем чтение файла
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуДанных);
// Читаем данные, указывая тип явно
ВсеДанные = Сериализатор.Фабрика.ПрочитатьXML(ЧтениеXML, Сериализатор.Фабрика.Тип("http://www.mycompany.com", "Данные"));
Важный момент: если вы используете СериализаторXDTO, платформа пытается сопоставить данные XML не только со схемой, но и с объектами метаданных 1С. Если ваша цель — просто получить объект XDTO (с которым удобно работать через точки), лучше использовать напрямую метод Фабрика.ПрочитатьXML(ЧтениеXML) без создания объекта СериализаторXDTO.
Разберем ситуацию, когда мы не можем изменить XSD, но нам нужно прочитать файл. Как обнаружил автор темы экспериментальным путем (сообщения 46-48), можно «обнулить» пространство имен для вложенных элементов прямо в тексте XML. Рассмотрим, как должен выглядеть файл, чтобы 1С прочитала его при настройке unqualified:
<Данные xmlns="http://www.mycompany.com">
<ДатаВыгрузки xmlns="">2023-10-27T10:00:00</ДатаВыгрузки>
<ГруппыАртикулов xmlns="">
<Код>001</Код>
</ГруппыАртикулов>
</Данные>
Добавление xmlns="" в каждый дочерний узел заставляет парсер считать эти элементы не принадлежащими никакому пространству имен. Это удовлетворяет требованию elementFormDefault="unqualified". Однако программно модифицировать каждый XML-файл перед чтением — трудоемкая задача, поэтому Способ 1 (правка схемы) остается приоритетным.
Проанализируем еще одну проблему, упомянутую в обсуждении: почему при чтении без указания второго параметра (типа) даты считываются как строки? Рассмотрим пример:
ВсеДанные = Фабрика.ПрочитатьXML(ЧтениеXML);
Если в самом XML-файле у узла не указан атрибут xsi:type="xs:dateTime", а фабрика не знает заранее, какой тип ожидать (так как мы не передали ТипXDTO вторым параметром), то 1С считывает значение как AnyType. В результате вместо объекта Дата вы получите обычную строку "2001-10-26T21:32:52".
Рекомендация: всегда передавайте в метод ПрочитатьXML ожидаемый тип корневого элемента. Это позволит фабрике корректно преобразовать простые типы XML (даты, числа, булево) в соответствующие типы 1С.
Стоит упомянуть и специфический баг, замеченный пользователями (сообщение 44). В некоторых релизах платформы 8.3 наблюдались проблемы при чтении файлов в кодировке UTF-8 с русскими символами, если символ попадал на границу буфера чтения. Если ваше чтение «вылетает» с невнятной ошибкой на файлах с кириллицей, попробуйте следующее:
ЧтениеXML явно указана кодировка, если она отличается от стандартной.ТекстовыйДокумент, а затем использовать ЧтениеXML.УстановитьСтроку().Подводя итог, можно сказать, что большинство проблем с XDTO при переходе на 8.3 решается через внимательный аудит пространств имен и установку «Квалифицированной формы элемента» в значение Истина. Это делает вашу интеграцию более устойчивой и соответствующей современным стандартам обмена данными.