При интеграции 1С с внешними системами через веб-сервисы разработчики часто сталкиваются с ошибкой: «Ошибка преобразования данных XDTO: НачалоСвойства...». Эта ситуация возникает в тот момент, когда мы пытаемся восстановить объект из XML-строки, полученной от внешней системы. Проблема кажется запутанной, так как данные визуально выглядят корректно, но платформа отказывается их принимать. В этой статье мы подробно разберем причины этой ошибки и рассмотрим правильные способы работы с объектами XDTO.
Рассмотрим стандартную ситуацию: через веб-сервис мы получаем объект типа ОбъектXDTO. Для удобства или логирования мы преобразуем его в строку с помощью функции ОбщегоНазначения.ОбъектXDTOВСтрокуXML. Однако, когда мы пытаемся выполнить обратное преобразование функцией ОбщегоНазначения.ЗначениеИзСтрокиXML, система выдает исключение.
Выясним причину. Функция ЗначениеИзСтрокиXML внутри себя использует объект СериализаторXDTO. Этот механизм предназначен исключительно для встроенных типов платформы 1С, таких как Структура, Массив, ТаблицаЗначений или ссылки на объекты метаданных (СправочникСсылка и др.).
Когда СериализаторXDTO встречает в XML данные, структура которых описана во внешней схеме XSD или передана сторонним сервисом (не по стандартам внутренней сериализации 1С), он не может сопоставить это «НачалоСвойства» ни с одним внутренним типом и выдает ошибку. Для работы с произвольными данными XDTO нужно использовать Фабрику XDTO.
Если в вашей конфигурации используется Библиотека стандартных подсистем (БСП), для работы с XDTO-объектами предусмотрены отдельные инструменты. Вместо универсальной функции ЗначениеИзСтрокиXML, проанализируем и применим функцию ОбъектXDTOИзСтрокиXML.
Этот метод специально адаптирован для десериализации данных, которые не являются системными типами 1С. Рассмотрим пример вызова:
// Получаем строку XML из внешнего источника или переменной
СтрокаXML = ПолучитьДанныеВФорматеXML();
// ТипXDTO - это объект типа ТипОбъектаXDTO, который мы ожидаем получить
// Его можно получить из пакета XDTO или фабрики
МойОбъект = ОбщегоНазначения.ОбъектXDTOИзСтрокиXML(СтрокаXML, ТипXDTO);
Если нам нужно более гибкое управление процессом или БСП недоступна, мы воспользуемся методом ПрочитатьXML самой фабрики. Это наиболее надежный способ, так как он позволяет явно указать схему, по которой будет производиться разбор.
Разберем процесс по шагам:
ЧтениеXML и загрузим в него нашу строку.ФабрикеXDTO (или созданной на основе вашей XSD-схемы).
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаXML);
// Если тип заранее известен (из пакета XDTO в конфигурации)
ТипОбъекта = ФабрикаXDTO.Тип("http://www.your-namespace.com", "Order");
РезультатXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение, ТипОбъекта);
// Если тип неизвестен (AnyType), можно пробовать читать без второго параметра
// РезультатXDTO = ФабрикаXDTO.ПрочитатьXML(Чтение);
Важный нюанс: Проанализируем пространство имен (Namespace). Если в XML-строке не указано URI пространства имен или оно пустое, это может привести к ошибке даже при использовании фабрики. Убедитесь, что передаваемый XML соответствует схеме, описанной в 1С.
Зачастую работать напрямую с объектом XDTO неудобно, особенно если нужно заполнять документ «Заказ покупателя». Мы можем преобразовать XDTO-объект в обычную структуру 1С. В БСП для этого есть удобный метод:
// Преобразует свойства XDTO в ключи структуры
ДанныеСтруктура = ОбменДаннымиXDTOСервер.ОбъектXDTOВСтруктуру(ОбъектXDTO);
Если же данные представляют собой список (массив объектов), нам потребуется обход в цикле для заполнения ТаблицыЗначений. Рассмотрим пример реализации:
ТЗ_Товары = Новый ТаблицаЗначений;
// Допустим, ОбъектXDTO содержит коллекцию "Items"
Если ОбъектXDTO.Items.Количество() > 0 Тогда
// Создаем колонки по свойствам первого элемента
Для Каждого Свойство Из ОбъектXDTO.Items[0].Тип().Свойства Цикл
ТЗ_Товары.Колонки.Добавить(Свойство.Имя);
КонецЦикла;
// Наполняем таблицу данными
Для Каждого ТекущийЭлемент Из ОбъектXDTO.Items Цикл
НоваяСтрока = ТЗ_Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ТекущийЭлемент);
КонецЦикла;
КонецЕсли;
Основная сложность при работе с веб-сервисами заключается в том, что обычная точка останова в коде модуля веб-сервиса может не сработать, так как обращение идет из внешнего сеанса. Посмотрим, как мы можем это обойти:
default.vrd в параметре debug установлено значение true. Также проверьте наличие файла конфигурации webservicecfg.xml в папке bin/conf сервера 1С.Подводя итог, отметим: если вы видите ошибку «НачалоСвойства», значит, вы пытаетесь использовать СериализаторXDTO там, где должна работать ФабрикаXDTO. Используйте правильные методы десериализации, проверяйте пространства имен и всегда имейте под рукой сохраненный XML-дамп для локальной отладки.