Работа с механизмами XDTO и XML в платформе «1С:Предприятие 8» является базовым навыком для реализации интеграций. Однако новички часто сталкиваются с неочевидными ошибками, такими как «Отсутствует отображение для типа "ОбъектXDTO"» или «Ошибочный порядок записи XML». В этой статье мы подробно разберем, почему возникают эти проблемы, в чем разница между СериализаторXDTO и ФабрикаXDTO, и как правильно выгружать данные справочников со всеми реквизитами.
Давайте проанализируем ситуацию: когда мы пытаемся использовать метод СериализаторXDTO.ЗаписатьXML(), передавая ему объект, созданный через ФабрикаXDTO.Создать(), система выдает ошибку. Это происходит из-за принципиального различия в назначении этих инструментов.
СериализаторXDTO — это «высокоуровневый» инструмент. Его главная задача — автоматически преобразовывать внутренние объекты 1С (такие как СправочникОбъект, ДокументОбъект, Массив или Структура) в XML на основе метаданных конфигурации. Он ожидает на вход именно «родные» типы платформы.
ФабрикаXDTO — это инструмент для работы с самой моделью данных XDTO. Когда мы программно создаем ОбъектXDTO по определенной схеме (пакету XDTO), мы уже работаем в пространстве типов XDTO. Пытаться передать ОбъектXDTO в СериализаторXDTO — это все равно что пытаться перевести с английского на русский текст, который уже написан на русском. Сериализатор просто не понимает, как сопоставить технический объект XDTO с типами метаданных, так как он ищет именно объекты 1С.
Решение: Если у вас уже есть ОбъектXDTO, его нужно записывать напрямую через фабрику:
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ПродуктXDTO);
Часто программисты замечают, что после успешного выполнения кода в XML-файле вместо заполненных реквизитов (наименование, артикул, цена) оказывается только UUID (уникальный идентификатор). Давайте выясним, почему так происходит.
В 1С существует разница между Ссылкой и Объектом.
СправочникСсылка — это лишь указатель на запись в базе данных. Она содержит только идентификатор.СправочникОбъект — это полные данные записи, считанные в оперативную память, включая все реквизиты и табличные части.Когда мы передаем в метод СериализаторXDTO.ЗаписатьXML() ссылку (полученную, например, через НайтиПоНаименованию() или НайтиПоКоду()), сериализатор логично записывает только то, что есть в ссылке — идентификатор. Чтобы выгрузить все данные, нам необходимо получить объект.
Рассмотрим правильный пример получения данных:
// Неправильно (выгрузит только ссылку):
ПродуктСсылка = Справочники.Продукт.НайтиПоНаименованию("Апельсин");
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ПродуктСсылка);
// Правильно (выгрузит все реквизиты):
ПродуктОбъект = Справочники.Продукт.НайтиПоНаименованию("Апельсин").ПолучитьОбъект();
Если ПродуктОбъект <> Неопределено Тогда
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ПродуктОбъект);
КонецЕсли;
Эта ошибка часто возникает при работе с пространствами имен (Namespaces). В 1С объект ЗаписьXML строго следит за соблюдением спецификации XML. Мы не можем записывать соответствия пространств имен «в пустоту».
Посмотрим на правильную последовательность действий, которую необходимо соблюдать:
ЗаписьXML и открытие файла или строки.ЗаписатьОбъявлениеXML()).ЗаписатьНачалоЭлемента()).ЗаписатьСоответствиеПространстваИмен().Если вы попытаетесь вызвать ЗаписатьСоответствиеПространстваИмен() до того, как открыли хотя бы один тег (элемент), система выдаст исключение. Это связано с тем, что пространства имен в XML всегда привязаны к конкретному узлу.
Предположим, нам нужно выгрузить список продуктов. Мы не будем создавать вручную пакеты XDTO, а воспользуемся встроенными возможностями платформы. Этот способ наиболее эффективен, если вы передаете данные между двумя базами 1С. Для постоянной синхронизации по расписанию на основе готовых XML-правил можно использовать программу для регулярного обмена данными между базами 1С.
Процедура ВыгрузитьДанныеЧерезСериализатор()
ИмяФайла = "C:\Обмен\Export.xml";
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла, "UTF-8");
// 1. Пишем заголовок файла
ЗаписьXML.ЗаписатьОбъявлениеXML();
// 2. Открываем корневой узел
ЗаписьXML.ЗаписатьНачалоЭлемента("ДанныеОбмена");
// 3. Указываем стандартные пространства имен (необязательно, но полезно для типизации)
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema");
ЗаписьXML.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Сериализатор = Новый СериализаторXDTO(ФабрикаXDTO);
// 4. Выбираем данные
Выборка = Справочники.Продукт.Выбрать();
Пока Выборка.Следующий() Цикл
// Важно: Получаем объект, а не ссылку!
ОбъектДанных = Выборка.ПолучитьОбъект();
// Записываем объект в XML
Сериализатор.ЗаписатьXML(ЗаписьXML, ОбъектДанных, НазначениеТипаXML.Явное);
КонецЦикла;
// 5. Закрываем теги и файл
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
Сообщить("Выгрузка завершена успешно!");
КонецПроцедуры
Если же ваша задача — выгрузить данные во внешнюю систему (например, на сайт или в банк), которая требует строго определенной структуры XML, отличающейся от внутренней структуры 1С, вам придется использовать ОбъектXDTO.
В этом случае последовательность действий будет следующей:
Процедура ВыгрузитьЧерезФабрику()
// Предположим, в конфигурации создан Пакет XDTO с именем "МойОбмен"
// и типом объекта "Товар", у которого есть свойства "Код", "Имя", "Цена".
ИмяФайла = "C:\Обмен\CustomExport.xml";
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(ИмяФайла);
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("Catalog");
ПродуктСсылка = Справочники.Продукт.НайтиПоНаименованию("Апельсин");
Если Не ПродуктСсылка.Пустая() Тогда
// Создаем объект XDTO на основании типа из пакета
ТипТовара = ФабрикаXDTO.Тип("http://www.mycompany.ru/exchange", "Товар");
ТоварXDTO = ФабрикаXDTO.Создать(ТипТовара);
// Заполняем свойства вручную
ТоварXDTO.Код = ПродуктСсылка.Код;
ТоварXDTO.Имя = ПродуктСсылка.Наименование;
ТоварXDTO.Цена = ПродуктСсылка.Цена; // Допустим, такой реквизит есть
// ВАЖНО: Используем Фабрику для записи, а не Сериализатор!
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ТоварXDTO);
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
КонецПроцедуры
Для того чтобы ваша выгрузка в XML работала стабильно и без ошибок, придерживайтесь следующих правил:
СериализаторXDTO для быстрой переброски данных между конфигурациями 1С и ФабрикуXDTO для формирования файлов по жестким внешним спецификациям (XSD).ПолучитьОбъект() перед передачей данных в сериализатор, если вам нужны свойства (реквизиты) этого объекта.ЗаписатьНачалоЭлемента) перед тем, как определять для него пространства имен.Понимание работы объектной модели XDTO позволяет создавать гибкие и надежные механизмы обмена данными. Несмотря на кажущуюся сложность, строгое следование правилам типизации и последовательности записи XML избавит вас от большинства трудностей при разработке. Для упрощения программного формирования сложных структур можно использовать фреймворк для генерации XML-документов.