Почему при импорте XSD в пакет XDTO в 1С к именам свойств добавляется «1» на конце и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с XML-схемами (XSD) и пакетами XDTO — стандартная задача для разработчика 1С, сталкивающегося с интеграционными механизмами. Однако стандартные инструменты платформы 1С:Предприятие при импорте и экспорте XSD-схем в метаданные конфигурации иногда ведут себя непредсказуемо. Разработчики часто сталкиваются с крайне неприятной ситуацией: после выгрузки схемы во внешний файл и её последующего обратного импорта в дерево метаданных конфигурации, имена некоторых свойств внезапно изменяются, получая цифровой суффикс на конце (например, Классификатор превращается в Классификатор1). Кроме того, нередко «слетают» ранее заданные базовые типы данных.

В этой статье мы подробно разберем внутренние механизмы платформы 1С, которые приводят к возникновению этих ошибок, проанализируем причины коллизий и рассмотрим три эффективных способа решения проблемы без потери структуры данных.

Причина №1: Конфликт пространств имен элементов и атрибутов в модели XDTO

Для того чтобы понять, откуда берется раздражающая единица на конце имени свойства, нам необходимо проанализировать разницу между архитектурой классического стандарта XML Schema (XSD) и внутренней моделью данных XDTO в платформе 1С.

В стандарте XSD элементы (elements) и атрибуты (attributes) представляют собой принципиально разные сущности XML-документа. Они находятся в разных пространствах имен внутри описания одного типа. Это означает, что с точки зрения стандарта XSD абсолютно легитимно спроектировать тип данных, у которого будет и атрибут с именем Классификатор, и вложенный элемент с точно таким же именем Классификатор. XML-парсеры легко отличат их друг от друга по синтаксическому контексту.

Однако в модели XDTO платформы 1С:Предприятие принят другой подход. При импорте схемы XSD все элементы и все атрибуты «схлопываются» в единый плоский список свойств (Properties) соответствующего ОбъектXDTO. Внутри одного типа XDTO имена всех свойств обязаны быть уникальными. Из-за этого платформа вынуждена разрешать коллизии имен по следующему жестко задокументированному алгоритму:

  1. Сначала парсер 1С последовательно обрабатывает все **атрибуты** XML-схемы и создает под них свойства XDTO. Свойство с именем Классификатор успешно регистрируется.
  2. Затем парсер переходит к обработке вложенных **элементов** в порядке их объявления.
  3. Обнаружив элемент с именем Классификатор, платформа видит, что свойство с таким именем уже существует (оно было создано на шаге обработки атрибутов).
  4. Чтобы избежать критической ошибки и не остановить импорт, платформа автоматически переименовывает конфликтующий элемент, добавляя к нему инкрементируемый числовой суффикс. Так рождается имя Классификатор1.

При повторном цикле экспорт-импорт ситуация может усугубляться, генерируя новые дубликаты свойств, если структура схемы регулярно перечитывается конфигуратором.

Причина №2: Сбой экспорта ограничений и потеря базовых типов

Вторая известная проблема связана со «слетанием» базовых типов (например, когда тип данных внезапно теряет наследование от стандартной строки xs:string или числа). Это происходит из-за внутренней ошибки генератора схем 1С.

Если в пакете XDTO у типа значения установлен базовый тип, но при этом не определены дополнительные ограничения (фасеты, такие как длина, паттерн или минимальное/максимальное значение), то при выгрузке пакета в XSD-файл платформа может сформировать некорректно закрытые теги ограничений (xs:restriction). При обратном импорте поврежденного файла парсер 1С просто не может распознать базовый тип и сбрасывает его значение в «Не определено».


Решение 1: Динамическое создание фабрики XDTO (Рекомендуемый метод)

Наиболее надежный и современный архитектурный подход при работе с XSD-схемами в 1С — это полный отказ от хранения схем в дереве метаданных конфигурации (в ветке «Общие — XDTO-пакеты»). Вместо этого схему XSD рекомендуется хранить в конфигурации как макет с типом Двоичные данные или Текстовый документ, а саму фабрику XDTO инициализировать непосредственно в программном коде во время выполнения (runtime).

Дело в том, что рантайм-парсер платформы при вызове функции СоздатьФабрикуXDTO работает значительно стабильнее, чем интерактивный конструктор пакетов в Конфигураторе, и не подвержен накоплению ошибок кэша метаданных.

Рассмотрим по шагам, как реализовать этот метод программно. Создадим процедуру, которая извлекает схему из макета двоичных данных, сохраняет её во временный файл и генерирует чистую фабрику XDTO:


Функция ПолучитьФабрикуXDTOИзМакеты() Экспорт
    
    // 1. Получаем макет двоичных данных, в котором хранится оригинальный XSD-файл
    МакетXSD = ПолучитьОбщийМакет("ИмяВашегоМакетаXSD");
    
    // 2. Формируем путь к временному файлу на диске
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xsd");
    
    // 3. Записываем двоичные данные во временный файл
    МакетXSD.Записать(ИмяВременногоФайла);
    
    // 4. Инициализируем фабрику XDTO на основе временного файла схемы
    Попытка
        НоваяФабрика = СоздатьФабрикуXDTO(ИмяВременногоФайла);
        УдалитьФайлы(ИмяВременногоФайла);
        Возврат НоваяФабрика;
    Исключение
        УдалитьФайлы(ИмяВременногоФайла);
        ЗаписатьЛогСобытий("Ошибка создания фабрики XDTO: " + ОписаниеОшибки(), УровеньЖурналаРегистрации.Ошибка);
        ВызватьИсключение "Не удалось инициализировать схему обмена XDTO.";
    КонецПопытки;
    
КонецФункции

Этот способ полностью гарантирует, что структура вашей XML-схемы не будет искажена платформой при сохранении конфигурации, а все типы данных останутся в исходном виде, разработанном в специализированных редакторах схем.

Решение 2: Программная подмена временного файла схемы через расширение

Бывают ситуации, когда вы работаете с типовым решением (например, БП, ERP или УХ), где интеграционный механизм жестко зашит в коде вендора. Стандартная процедура конфигурации может извлекать XSD-схему из своего предопределенного макета, сохранять её во временную папку и строить по ней фабрику. Если при этом вы сталкиваетесь с описываемым багом переименования полей, можно применить элегантный перехват события через механизм расширений.

Используя аннотацию &После, мы можем перехватить процедуру генерации временного файла схемы и заменить содержимое этого файла на нашу исправленную XSD-схему непосредственно перед тем, как платформа вызовет метод создания фабрики. Проанализируем пример такого перехвата:


&После("ПодготовитьВременныеФайлыСхемы")
Процедура Расш_ПодготовитьВременныеФайлыСхемыПосле(ПараметрыСтруктуры)
    
    // Предположим, структура содержит путь к созданному платформой временному файлу XSD
    ПутьКФайлуТиповойСхемы = ПараметрыСтруктуры.ПутьКФайлуСхемы;
    
    // Получаем наше исправленное содержимое схемы из нашего собственного макета расширения
    МакетИсправленный = УправлениеРасширениями.ПолучитьМакет("МойИсправленныйXSD");
    
    // Записываем наше корректное содержимое поверх сгенерированного платформой временного файла
    МакетИсправленный.Записать(ПутьКФайлуТиповойСхемы);
    
    // Теперь, когда типовой код вызовет СоздатьФабрикуXDTO(ПутьКФайлуСхемы), 
    // он загрузит нашу чистую, неискаженную схему без суффиксов "1"
    
КонецПроцедуры

Решение 3: Локальное исправление схемы в Notepad++

Если вам все же критически необходимо использовать именно визуальный пакет XDTO в дереве метаданных конфигурации, единственным выходом остается ручная коррекция XSD-файла перед импортом.

Разберем алгоритм ручной очистки коллизий:

  1. Откройте выгруженный XSD-файл в текстовом редакторе (например, Notepad++ или VS Code).
  2. Воспользуйтесь глобальным поиском по файлу, чтобы найти конфликтующие имена элементов и атрибутов. Если вы обнаружили, например, атрибут name="Классификатор" и элемент name="Классификатор" внутри одного complexType, переименуйте один из них на уровне проектирования схемы (например, атрибут назовите ID_Классификатор или КодКлассификатора).
  3. Если у вас «слетают» базовые типы данных при импорте, найдите в XSD-файле теги ограничений:
    
    <xs:simpleType name="ИмяТипа">
        <xs:restriction base="xs:string">
        </xs:restriction>
    </xs:simpleType>
    
    Убедитесь, что тег xs:restriction оформлен корректно и содержит базовый тип. Если он пустой, платформа 1С при импорте может проигнорировать его. Попробуйте явно задать хотя бы минимальное ограничение (например, длину строки) или удалите пустой блок ограничений, оставив простое объявление типа.
  4. Сохраните изменения в файле.
  5. Перед повторным импортом файла обязательно удалите старый пакет XDTO из конфигурации, выполните операцию «Обновить конфигурацию базы данных» (F7) и полностью перезапустите Конфигуратор. Это необходимо для полной очистки кэша метаданных платформы, который часто хранит старые связи типов.

Используя предложенные методы, вы сможете раз и навсегда решить проблемы несовместимости при импорте/экспорте XDTO-пакетов и настроить стабильный обмен данными с внешними информационными системами.

← На главную