При работе с внешними системами обмена данными программисты 1С часто сталкиваются с необходимостью импорта готовых XSD-схем в дерево метаданных конфигурации (XDTO-пакеты). Однако нередко возникает ситуация, когда после успешного, на первый взгляд, импорта структура пакета оказывается "пустой" или в ней отсутствуют вложенные свойства и элементы. Рассмотрим подробно, почему это происходит, проанализируем типичные ошибки в структуре XSD и разберем правильные способы построения схемы для корректной работы в платформе 1С.
Проанализируем базовый механизм работы XDTO. Платформа 1С:Предприятие при импорте XSD строго следует спецификациям консорциума W3C. Основная проблема, с которой сталкиваются разработчики (как показано в сообщениях темы), заключается в попытке вложить один xs:element непосредственно в другой xs:element. В стандарте XML Schema такая структура является невалидной.
Разберем по шагам правила вложенности:
xs:element) — это описание конкретного поля или тега в XML-файле.xs:complexType).xs:sequence (последовательность), xs:choice (выбор) или xs:all (совокупность в любом порядке).Посмотрим на пример некорректной схемы, которая часто встречается у новичков и приводит к потере данных при импорте:
<xs:element name="Root">
<xs:element name="Spisok"> <!-- ОШИБКА: Элемент вложен прямо в элемент без complexType -->
<xs:complexType>
<xs:sequence>
<xs:element name="Item" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:element>
При импорте такой схемы 1С может создать объект Root, но проигнорирует все, что находится внутри него, так как структура нарушает логику парсера.
Рассмотрим ситуацию, когда нам нужно создать иерархию: корневой элемент Root, внутри него список Spisok, а внутри списка — набор контрагентов. Чтобы 1С корректно построила дерево XDTO, мы должны явно указать контейнеры типов.
Правильный вариант структуры выглядит так:
<xs:schema xmlns:tns="http://www.test.ru/ar"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.test.ru/ar"
elementFormDefault="qualified">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Spisok">
<xs:complexType>
<xs:sequence>
<!-- Здесь описываются вложенные элементы -->
<xs:element name="Kontragent" type="tns:KontragentType" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="Tip" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="KontragentType">
<xs:sequence>
<xs:element name="YurLitso" type="xs:string"/>
<xs:element name="FizLitso" type="xs:string"/>
</xs:sequence>
<xs:attribute name="Kod" type="xs:string" use="required"/>
<xs:attribute name="Naimenovanie" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
В данном примере мы использовали именованный тип KontragentType. Это хорошая практика, так как она позволяет повторно использовать описание объекта и делает структуру прозрачной для механизмов 1С.
В обсуждении часто упоминается использование атрибута ref (<xs:element ref="Kontragent"/>). Важно понимать, что ref работает только в том случае, если элемент, на который вы ссылаетесь, объявлен как глобальный (т.е. он находится на первом уровне вложенности внутри тега xs:schema). Если вы объявили элемент внутри другого типа, ссылка на него по имени через ref будет невалидной, и 1С снова "потеряет" это свойство при импорте.
Проанализируем ситуацию: если вы получили схему от стороннего разработчика и она не загружается, проверьте наличие всех глобальных определений. Если элемент Kontragent используется через ref, он обязан существовать в корне схемы.
Иногда схема бывает настолько сложной или некорректной с точки зрения конфигуратора 1С, что добавить ее в дерево метаданных как Пакет XDTO не представляется возможным. В этом случае мы можем воспользоваться программным методом загрузки схемы без ее фиксации в метаданных.
Рассмотрим, как это реализовать в коде:
// Предположим, файл схемы лежит на диске или в макете
ПутьКСхеме = "C:\Schemas\MySchema.xsd";
МассивСхем = Новый Массив;
МассивСхем.Добавить(ПутьКСхеме);
Построитель = Новый ПостроительДокументаDOM;
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКСхеме);
ДокументDOM = Построитель.Прочитать(Чтение);
СхемаXML = Новый СхемаXML;
СхемаXML.РасположениеСхемы = ПутьКСхеме;
НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(СхемаXML);
// Создаем фабрику XDTO динамически
МояФабрика = СоздатьФабрикуXDTO(НаборСхем);
// Теперь можно создавать объекты по типам из этой схемы
ТипОбъекта = МояФабрика.Тип("http://www.test.ru/ar", "Root");
НовыйОбъект = МояФабрика.Создать(ТипОбъекта);
Этот метод позволяет обойти жесткие ограничения конфигуратора при импорте и работать со схемами "на лету". Однако помните, что при динамическом создании фабрики вы теряете возможность типизации в коде через ФабрикаXDTO.Тип(...) для пакетов, встроенных в конфигурацию.
XDTO вручную в дереве метаданных. Создайте Объект (тип объекта), добавьте в него Свойства. Затем выгрузите этот пакет в XSD и сравните с эталонным файлом. Это поможет понять, какой именно иерархии ожидает 1С.complexType name="..."). Анонимные типы (объявленные внутри элемента) в 1С часто превращаются в трудночитаемые структуры вложенных свойств.targetNamespace в заголовке схемы совпадает с пространством имен, которое вы указываете в пакете XDTO. Ошибки в URI пространства имен — одна из самых частых причин "невидимости" типов.Таким образом, успех импорта XSD в 1С напрямую зависит от соблюдения строгой иерархии: Элемент -> Тип -> Композитор -> Вложенные элементы. Исправив структуру вашей схемы в соответствии с этими правилами, вы получите корректное дерево объектов в пакете XDTO и сможете полноценно использовать механизмы сериализации платформы.