При организации обмена данными между различными конфигурациями 1С (например, между самописной системой и «1С:Бухгалтерией») программисты часто сталкиваются с ошибкой: «Не удалось десериализовать объект... возможно поменялась структура конфигурации: Ошибка при вызове метода контекста (ПрочитатьXML)». Эта проблема возникает в момент, когда принимающая база пытается преобразовать входящий XML-поток в объект XDTO, но структура этого потока не соответствует ожиданиям схемы XDTO-пакета.
В этой статье мы подробно разберем, почему возникает такая ошибка, как проанализировать состав пакетов и какие шаги предпринять для восстановления работоспособности обмена.
Проанализируем ситуацию: метод ПрочитатьXML в контексте работы с XDTO крайне чувствителен к любым отклонениям от схемы. Основными причинами сбоя обычно являются:
xs:sequence. Это означает, что 1С ожидает увидеть поля в XML-файле строго в том порядке, в котором они описаны в пакете. Если поле IsFolder идет первым в одной базе и вторым в другой — десериализация упадет.string, а в другой — ссылку на перечисление.Посмотрим на пример кода, который обычно используется для отправки пакета через Web-сервис:
Функция ОтправитьПакетДанныхВСмежнуюБазу(СтруктураОтправкиПакета)
СтруктураОтправкиПакета.НомерПакета = СтруктураОтправкиПакета.НомерПакета + 1;
XML_Message = ПолучитьТекстСообщенияПакетаДанных(СтруктураОтправкиПакета.Пакет);
// Преобразование XML с помощью XSLT для приведения к структуре приемника
XML_Message_Recipient_Struckure = ПреобразоватьТекстВСтруктуруПриемника(XML_Message, СтруктураОтправкиПакета);
Если XML_Message_Recipient_Struckure = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Попытка
// Вызов метода Web-сервиса в приемнике
РезультатЗагрузки = СтруктураОтправкиПакета.ПроксиWSСсылкиОбменаСоСмежнойБазой.uploadDataPackage(
XML_Message_Recipient_Struckure,
СтруктураОтправкиПакета.НомерПакета,
СтруктураОтправкиПакета.Приоритет,
СтруктураОтправкиПакета.СразуСтавитьВОчередь,
СтруктураОтправкиПакета.СтруктураИдентификацииСообщения.Ид);
Исключение
// Обработка ошибки соединения
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции
Выясним причину расхождения, выгрузив схемы XSD из обеих конфигураций. Для этого в дереве метаданных нужно найти используемый XDTO-пакет, нажать на него правой кнопкой мыши и выбрать «Экспорт XML-схемы».
Рассмотрим пример реального расхождения для справочника ОбщероссийскийКлассификаторОсновныхФондов. В самописной базе схема выглядит так:
<xs:complexType name="CatalogObject.ОбщероссийскийКлассификаторОсновныхФондов">
<xs:sequence>
<xs:element name="IsFolder" type="xs:boolean"/>
<xs:element name="Ref" type="tns:CatalogRef.ОбщероссийскийКлассификаторОсновныхФондов"/>
<xs:element name="DeletionMark" type="xs:boolean"/>
<xs:element name="Parent" type="tns:CatalogRef.ОбщероссийскийКлассификаторОсновныхФондов"/>
<xs:element name="Code" type="xs:string"/>
<xs:element name="Description" type="xs:string"/>
<xs:element name="КонтрольноеЧисло" type="xs:string"/>
<xs:element name="НаименованиеГруппировки" type="xs:string"/>
<xs:element name="АмортизационнаяГруппа" type="tns:EnumRef.АмортизационныеГруппы"/>
<xs:element name="хлпКоэффициентУскорения" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
А в базе «1С:Бухгалтерия» порядок и состав элементов другие:
<xs:complexType name="CatalogObject.ОбщероссийскийКлассификаторОсновныхФондов">
<xs:sequence>
<xs:element name="Ref" type="tns:CatalogRef.ОбщероссийскийКлассификаторОсновныхФондов"/>
<xs:element name="DeletionMark" type="xs:boolean"/>
<xs:element name="Parent" type="tns:CatalogRef.ОбщероссийскийКлассификаторОсновныхФондов"/>
<xs:element name="Code" type="xs:string"/>
<xs:element name="Description" type="xs:string"/>
<xs:element name="PredefinedDataName" type="xs:string" minOccurs="0"/>
<xs:element name="КонтрольноеЧисло" type="xs:string"/>
<xs:element name="НаименованиеГруппировки" type="xs:string"/>
</xs:sequence>
</xs:complexType>
Важное наблюдение: В приемнике отсутствует поле хлпКоэффициентУскорения, а поле IsFolder вообще не предусмотрено в начале последовательности. Это гарантированно приведет к ошибке ПрочитатьXML, так как механизм XDTO в 1С ожидает элементы строго по списку.
Разберем по шагам, как можно исправить данную ситуацию. У нас есть два основных пути.
Это самый правильный метод. Нам необходимо привести структуру пакета в базе-приемнике к виду базы-источника (или наоборот).
хлпКоэффициентУскорения) с соответствующими типами.iisreset для IIS), так как описания пакетов кэшируются.Если вы не хотите менять структуру конфигурации «1С:Бухгалтерия», вы можете подправить XSLT-шаблон, который используется в функции ПреобразоватьТекстВСтруктуруПриемника. Настройте шаблон так, чтобы он:
хлпКоэффициентУскорения).xs:sequence приемника.Чтобы точно понять, на каком поле спотыкается система, необходимо запустить отладку на стороне Web-сервиса базы-приемника. Рассмотрим, как это сделать:
-debug.uploadDataPackage).ПрочитатьXML и увидеть, какой именно элемент вызывает ошибку.Проанализировав состав передаваемого XML-пакета и сравнив его со схемой в конфигураторе, вы сможете быстро устранить причину десериализации. Помните, что XDTO — это строгая типизация, и любое отклонение в имени, типе или порядке полей является критическим для платформы 1С.