При разработке механизмов обмена данными между конфигурациями, которые имеют общую базу, но были доработаны независимо друг от друга, разработчики часто сталкиваются с проблемой «жесткой» типизации XDTO. В ситуациях, когда источник данных содержит дополнительные свойства, которых нет в принимающей конфигурации, штатный сериализатор вызывает исключение. Давайте разберемся, почему это происходит и как можно обойти данное ограничение.
Основная причина заключается в том, что системный пакет http://v8.1c.ru/8.1/data/enterprise/current-config является «зеркалом» структуры метаданных конкретной конфигурации. Когда мы используем СериализаторXDTO, платформа ожидает строгого соответствия структуры входящего XML текущей схеме метаданных.
Важно понимать: свойство «Открытый» у объекта ТипОбъектаXDTO недоступно для изменения из встроенного языка, так как этот пакет является системным и автоматически обновляется платформой. Мы не можем «подменить» его «на лету» для штатного механизма сериализации, так как сериализатор всегда обращается к текущей, жестко определенной структуре.
Так как прямое изменение системного пакета невозможно, рассмотрим альтернативные подходы для реализации обмена в условиях различия метаданных:
Вместо того чтобы доверять автоматической десериализации, мы можем использовать инструменты низкоуровневой работы с XML. Это позволит нам «отфильтровать» данные перед тем, как они попадут в объекты метаданных.
Разберем логику такого подхода:
XML файл в объект ЧтениеXML или создаем DOM-модель документа.Метаданные).XML в СериализаторXDTO.Если мы хотим использовать XDTO на полную мощность, мы можем создать свой пакет описания данных. Однако помните, что при этом меняется пространство имен.
Рассмотрим пример создания своего пакета:
// Создаем свой пакет на основе системного, но меняем его пространство имен
Пакет = ФабрикаXDTO.СоздатьПакет("http://my-namespace.ru/custom-config");
// Теперь при записи мы используем свои типы и пространства имен
Запись = Новый ЗаписьXML;
// ... настройки записи
Важно: при таком подходе после десериализации вы получите не «нативный» объект (например, СправочникОбъект), а универсальный объект ОбъектXDTO. Это дает гибкость, но требует от нас написания кода для переноса данных из ОбъектXDTO в реальные объекты метаданных.
ЗаписьXML и ЧтениеXMLЕсли автоматизация через XDTO становится слишком сложной, мы можем отказаться от нее в пользу простого перебора узлов. Объект ЗаписьXML позволяет гибко управлять записью элементов, используя метод ЗаписатьНачалоЭлемента.
Пример работы с ЗаписьXML:
Запись = Новый ЗаписьXML;
Запись.ОткрытьФайл("C:\Data.xml");
Запись.ЗаписатьОбъявлениеXML();
Запись.ЗаписатьНачалоЭлемента("Данные");
// Вручную записываем поля, которые точно есть в обеих конфигурациях
Запись.ЗаписатьЭлемент("Код", Объект.Код);
Запись.ЗаписатьЭлемент("Наименование", Объект.Наименование);
// Лишние поля просто игнорируем
Запись.ЗаписатьКонецЭлемента();
Запись.Закрыть();
Подводя итог нашей совместной работе, можно выделить следующие ключевые моменты:
XML, предварительная обработка (удаление неизвестных узлов) сэкономит много времени при импорте.XDTO.Используйте этот опыт, чтобы сделать ваши механизмы обмена данными более устойчивыми к изменениям в конфигурациях!