При работе с обменом данными в формате XML через механизмы XDTO программисты часто сталкиваются с ситуацией, когда стандартная сериализация «по ссылке» (UUID) не подходит. Например, когда базы создавались независимо и идентификаторы одних и тех же подразделений или контрагентов в них различаются. В таких случаях требуется перенастроить логику приема данных: реализовать поиск по наименованию, коду или комбинации реквизитов (дата и номер документа).
В этой статье мы подробно разберем, как модифицировать XDTO-пакеты, как добавлять в них новые объекты метаданных и какими программными способами можно изменить поведение системы при чтении XML-файла.
Прежде чем приступать к редактированию, проанализируем природу пакетов в 1С. Пакет с пространством имен http://v8.1c.ru/8.1/data/enterprise/current-config является динамическим. Платформа генерирует его автоматически на лету, исходя из текущего состава метаданных вашей конфигурации.
Если вы добавили новый документ (например, СоглашениеОВнутреннейКооперации) в дерево конфигурации, он должен автоматически появиться в этом пакете. Однако, если при попытке загрузки возникает ошибка преобразования типов, это часто означает, что изменения метаданных еще не зафиксированы в базе данных или структура XML-файла не соответствует ожидаемой. Рассмотрим основные причины таких ошибок:
Рассмотрим ситуацию: в XML-файле передается подразделение в виде строки с названием, а стандартный механизм XDTO ожидает ссылку типа CatalogRef.СтруктураПредприятия. Попытка прямой загрузки приведет к ошибке, так как строка «Отдел 10» не является валидным GUID.
Для решения этой задачи мы можем использовать один из следующих подходов:
Если мы используем статический (созданный вручную) пакет XDTO, мы можем изменить тип реквизита. Вместо ссылки на справочник укажем базовый тип string (из пространства имен http://www.w3.org/2001/XMLSchema). Это позволит платформе успешно прочитать текстовое значение из XML в объект XDTO.
После того как данные прочитаны в ОбъектXDTO, выполним программный поиск перед созданием документа в 1С:
// Предположим, мы прочитали данные из файла
ОбъектXDTO = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
// Выполняем поиск по наименованию, полученному из XML
НаименованиеПодразделения = ОбъектXDTO.Подразделение;
СсылкаНаПодразделение = Справочники.СтруктураПредприятия.НайтиПоНаименованию(НаименованиеПодразделения);
Если СсылкаНаПодразделение.Пустая() Тогда
// Здесь можно реализовать логику создания нового элемента, если он не найден
НовоеПодразделение = Справочники.СтруктураПредприятия.СоздатьЭлемент();
НовоеПодразделение.Наименование = НаименованиеПодразделения;
НовоеПодразделение.Записать();
СсылкаНаПодразделение = НовоеПодразделение.Ссылка;
КонецЕсли;
// Устанавливаем найденную ссылку в создаваемый документ 1С
ДокументОбъект.Подразделение = СсылкаНаПодразделение;
Если структура входящего XML-файла жестко задана и мы не можем менять XDTO-пакет, проанализируем возможность использования механизма ПреобразованиеXSL. Это мощный инструмент, который позволяет трансформировать исходный XML в другой формат до того, как он попадет на вход XDTO-сериализатору.
С помощью XSLT-шаблона можно на лету переименовывать узлы, менять их типы или добавлять технические атрибуты, которые помогут системе идентификации 1С правильно сопоставить объекты. Это особенно полезно при интеграции с внешними системами, которые ничего не знают о структуре метаданных 1С.
При попытке ручного редактирования XDTO-пакета в конфигураторе часто возникает проблема: создаваемый объект получает имя по умолчанию (например, Объект1), и его не удается переименовать или привязать к метаданным. Выясним причину этой проблемы.
Чтобы корректно добавить новый тип в пакет, выполним следующие шаги:
DocumentObject.ИмяДокумента).Если объектов очень много, рекомендуется создать схему (XSD-файл) в специализированном редакторе и импортировать её в 1С. Это позволит избежать ошибок ручного ввода имен и пространств имен.
Разберем типичную ошибку: «Отображение лексического значения '' в значение типа...». Проанализируем ситуацию: в XML-файле присутствует тег (например, <v8:Подразделение/>), но он не содержит данных. При попытке преобразовать эту «пустоту» в ссылку на справочник платформа выдает ошибку.
Чтобы избежать этого, в свойствах соответствующего типа в XDTO-пакете установим следующие флаги:
True. Это позволит передавать пустое значение (nil).0. Это позволит тегу вообще отсутствовать в XML-файле без вызова ошибки.Если стоит задача найти существующий документ в базе по номеру и дате, присланным в XML, механизм автоматической сериализации не сделает это за вас. После десериализации XML в объект XDTO необходимо выполнить поиск вручную:
// Извлекаем данные из XDTO
НомерДок = ОбъектXDTO.Номер;
ДатаДок = ОбъектXDTO.Дата;
// Ищем документ в базе
ДокСсылка = Документы.СоглашениеОВнутреннейКооперации.НайтиПоНомеру(НомерДок, ДатаДок);
Если Не ДокСсылка.Пустая() Тогда
ДокументОбъект = ДокСсылка.ПолучитьОбъект();
Иначе
ДокументОбъект = Документы.СоглашениеОВнутреннейКооперации.СоздатьДокумент();
ДокументОбъект.Номер = НомерДок;
ДокументОбъект.Дата = ДатаДок;
КонецЕсли;
// Продолжаем заполнение реквизитов...
В случае использования обмена через формат EnterpriseData, логика поиска по полям (ключевым свойствам) описывается в модуле менеджера обмена. Там можно указать, что идентификация должна происходить не по GUID, а по полям Наименование или Код, используя коллекцию КлючевыеСвойства в XML-файле.
Таким образом, для гибкой настройки приема данных через XDTO мы имеем целый арсенал средств: от простого изменения типов в схеме до программной обработки ОбъектаXDTO и применения XSL-трансформаций. Выбор метода зависит от того, насколько часто меняется структура данных и есть ли возможность влиять на формат выгрузки в базе-источнике.