Как исправить ошибку преобразования XDTO при чтении XML в 1С

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

Работа с механизмом XDTO (XML Data Transfer Objects) в 1С является мощным инструментом для интеграции, однако она требует строгого соблюдения стандартов W3C XML Schema. Часто программисты сталкиваются с трудночитаемыми ошибками вроде «Структура объекта не соответствует типу», даже если визуально XML-файл кажется верным. Проанализируем типичные причины возникновения таких проблем и найдем правильные способы их решения.

Разбор основной ошибки: Порядок следования элементов и атрибутов

Одной из самых распространенных причин отказа 1С принимать схему XSD является нарушение последовательности описания свойств внутри complexType. В языке определения схем XML существует жесткое правило: все вложенные элементы (описанные через xs:sequence, xs:choice или xs:all) должны располагаться строго ДО описания атрибутов (xs:attribute).

Рассмотрим ситуацию, с которой столкнулся автор темы. В его исходной схеме атрибуты были перемешаны с последовательностью элементов или шли перед ней. Проанализируем, как должна выглядеть правильная структура на примере типа Данные:


<xs:complexType name="Данные">
    <xs:sequence>
        <xs:element name="Реализации" type="tns:Реализации" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="ОрганизацияИНН" type="xs:string"/>
    <xs:attribute name="Дата1" type="xs:date"/>
    <xs:attribute name="Дата2" type="xs:date"/>
    <xs:attribute name="ВремяВыгрузки" type="xs:string"/>
</xs:complexType>

Обратите внимание: блок xs:sequence закрывается до того, как начинаются определения xs:attribute. Если вы поменяете их местами, Фабрика XDTO в 1С выдаст ошибку валидации при попытке прочитать XML-данные, так как парсер ожидает увидеть структуру в строго определенном стандартом порядке.

Проблема пространств имен (Namespace)

Выясним еще одну важную причину, по которой 1С может «не видеть» данные в файле. Это несоответствие пространств имен (Namespaces). В схеме автора указан targetNamespace="http://localhost/testXML". Это означает, что все элементы, описанные в этой схеме, принадлежат данному пространству.

Если в вашем XML-файле корневой тег выглядит просто как <Данные> без указания xmlns, то 1С не сможет сопоставить его с типом из схемы. Рассмотрим два варианта решения этой проблемы:

  1. Добавление пространства имен в XML: Ваш файл должен начинаться примерно так: <Данные xmlns="http://localhost/testXML" ... >.
  2. Настройка схемы: Если вы не можете влиять на формат входящего XML, уберите targetNamespace из строки схемы и установите параметры elementFormDefault="unqualified".

Проанализируем также атрибут elementFormDefault. Если установлено значение qualified, то все вложенные элементы (Реализации, СтрокаТЧ) также должны быть явно соотнесены с пространством имен схемы в исходном XML-файле.

Отсутствие декларации глобального элемента

В схемах XDTO важно различать Тип объекта и сам Элемент. В коде автора описаны только complexType. Однако для того, чтобы метод ПрочитатьXML сработал корректно, фабрика должна знать, какой элемент является корневым. Рекомендуется добавлять в корень схемы декларацию элемента:

<xs:element name="Данные" type="tns:Данные"/>

Без этой строки фабрика может успешно создать типы, но не «узнает» начало документа при чтении из ЧтениеXML.

Типизация данных: Булевы значения и даты

Разберем ситуацию со значениями атрибутов. В примере автора атрибут ОрганизацияПлательщикНДС имеет значение "1", а тип в схеме — xs:boolean. Согласно спецификации XML, значениями для boolean могут быть true, false, 1 или 0. Однако 1С при строгой проверке иногда может требовать соответствия внутренним представлениям.

Аналогично с датами. Тип xs:date ожидает формат YYYY-MM-DD. Если в вашем файле дата передается в формате DD.MM.YY (как в поле ВремяВыгрузки в примере), то использование типа xs:date приведет к ошибке. В таких случаях используйте xs:string и преобразуйте дату программно после загрузки.

Реализация загрузки в коде 1С

Посмотрим на пример кода, который позволит правильно загрузить данные, используя подготовленную схему. Предположим, что СтрокаXSD — это ваша выверенная строка со схемой.


// Создадим фабрику на основании схемы
ИмяФайлаСхемы = ПолучитьИмяВременногоФайла("xsd");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(СтрокаXSD);
ТекстовыйДокумент.Записать(ИмяФайлаСхемы, КодировкаТекста.UTF8);

Модель = ФабрикаXDTO.СоздатьМодельXSD(ИмяФайлаСхемы);
МояФабрика = Новый ФабрикаXDTO(Модель);

// Читаем файл
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуXML);

Попытка
    ДанныеОбъекта = МояФабрика.ПрочитатьXML(ЧтениеXML);
    // Теперь можно обращаться к свойствам: ДанныеОбъекта.ОрганизацияИНН
Исключение
    Сообщить("Ошибка чтения: " + ОписаниеОшибки());
КонецПопытки;

Ошибка "Content Is Not Allowed In Prolog"

Если при попытке валидации или чтения вы получаете сообщение «Content Is Not Allowed In Prolog», это означает, что в самом начале вашего XML-файла (до тега <?xml ...?>) находятся лишние символы. Часто это BOM (Byte Order Mark) — невидимые символы, которые добавляют некоторые текстовые редакторы при сохранении в UTF-8. При работе в 1С рекомендуется открывать файл с явным указанием кодировки или предварительно очищать строку от непечатаемых символов.

Альтернативный подход: Использование объектной модели DOM

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

Выясним, как это реализовать:


ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ПутьКФайлуXML);
ПостроительDOM = Новый ПостроительDOM;
ДокументDOM = ПостроительDOM.Прочитать(ЧтениеXML);

// Поиск узлов через XPath или перебором
СписокРеализаций = ДокументDOM.ПолучитьЭлементыПоИмени("Реализация");
Для Каждого УзелРеализация Из СписокРеализаций Цикл
    Номер = УзелРеализация.Атрибуты.ПолучитьИмя(0).Значение; // Пример получения атрибута
    // Обработка данных
КонецЦикла;

Подводя итог, отметим, что для победы над схемой XDTO необходимо:

  1. Следить за тем, чтобы xs:attribute всегда шли после xs:sequence.
  2. Проверять соответствие targetNamespace в схеме и xmlns в XML.
  3. Убедиться, что типы данных (date, boolean, decimal) в схеме соответствуют строковому представлению в файле.

Использование этих правил позволит вам избежать большинства ошибок при десериализации данных в 1С.

← На главную