Почему при импорте XSD в пакет XDTO 1С пропадают вложенные элементы и как это исправить?

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

При работе с внешними системами обмена данными программисты 1С часто сталкиваются с необходимостью импорта готовых XSD-схем в дерево метаданных конфигурации (XDTO-пакеты). Однако нередко возникает ситуация, когда после успешного, на первый взгляд, импорта структура пакета оказывается "пустой" или в ней отсутствуют вложенные свойства и элементы. Рассмотрим подробно, почему это происходит, проанализируем типичные ошибки в структуре XSD и разберем правильные способы построения схемы для корректной работы в платформе 1С.

Выясняем причину: почему 1С "не видит" вложенность

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

Разберем по шагам правила вложенности:

  1. Элемент (xs:element) — это описание конкретного поля или тега в XML-файле.
  2. Чтобы элемент мог содержать внутри себя другие элементы (т.е. быть объектом, а не простым значением), он должен обладать сложным типом (xs:complexType).
  3. Внутри сложного типа обязательно должен быть определен композитор — правило, по которому располагаются дочерние элементы. Чаще всего это 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, но проигнорирует все, что находится внутри него, так как структура нарушает логику парсера.

Исправляем структуру XSD для корректного импорта

Рассмотрим ситуацию, когда нам нужно создать иерархию: корневой элемент 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)

В обсуждении часто упоминается использование атрибута ref (<xs:element ref="Kontragent"/>). Важно понимать, что ref работает только в том случае, если элемент, на который вы ссылаетесь, объявлен как глобальный (т.е. он находится на первом уровне вложенности внутри тега xs:schema). Если вы объявили элемент внутри другого типа, ссылка на него по имени через ref будет невалидной, и 1С снова "потеряет" это свойство при импорте.

Проанализируем ситуацию: если вы получили схему от стороннего разработчика и она не загружается, проверьте наличие всех глобальных определений. Если элемент Kontragent используется через ref, он обязан существовать в корне схемы.

Альтернативный подход: Программное создание фабрики XDTO

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

Рассмотрим, как это реализовать в коде:


// Предположим, файл схемы лежит на диске или в макете
ПутьКСхеме = "C:\Schemas\MySchema.xsd";
МассивСхем = Новый Массив;
МассивСхем.Добавить(ПутьКСхеме);

Построитель = Новый ПостроительДокументаDOM;
Чтение = Новый ЧтениеXML;
Чтение.ОткрытьФайл(ПутьКСхеме);
ДокументDOM = Построитель.Прочитать(Чтение);

СхемаXML = Новый СхемаXML;
СхемаXML.РасположениеСхемы = ПутьКСхеме;

НаборСхем = Новый НаборСхемXML;
НаборСхем.Добавить(СхемаXML);

// Создаем фабрику XDTO динамически
МояФабрика = СоздатьФабрикуXDTO(НаборСхем);

// Теперь можно создавать объекты по типам из этой схемы
ТипОбъекта = МояФабрика.Тип("http://www.test.ru/ar", "Root");
НовыйОбъект = МояФабрика.Создать(ТипОбъекта);

Этот метод позволяет обойти жесткие ограничения конфигуратора при импорте и работать со схемами "на лету". Однако помните, что при динамическом создании фабрики вы теряете возможность типизации в коде через ФабрикаXDTO.Тип(...) для пакетов, встроенных в конфигурацию.

Практические советы по отладке XSD

  1. Используйте внешние валидаторы. Прежде чем импортировать схему в 1С, проверьте ее на соответствие стандарту XML Schema в сторонних сервисах. Если валидатор сообщает об ошибке, 1С гарантированно не сможет корректно прочитать структуру.
  2. Ручное создание в конфигураторе. Если схема небольшая, самый надежный способ — создать пакет XDTO вручную в дереве метаданных. Создайте Объект (тип объекта), добавьте в него Свойства. Затем выгрузите этот пакет в XSD и сравните с эталонным файлом. Это поможет понять, какой именно иерархии ожидает 1С.
  3. Анонимные типы против именованных. Старайтесь всегда давать имена сложным типам (complexType name="..."). Анонимные типы (объявленные внутри элемента) в 1С часто превращаются в трудночитаемые структуры вложенных свойств.
  4. Пространства имен (Namespace). Убедитесь, что targetNamespace в заголовке схемы совпадает с пространством имен, которое вы указываете в пакете XDTO. Ошибки в URI пространства имен — одна из самых частых причин "невидимости" типов.

Таким образом, успех импорта XSD в 1С напрямую зависит от соблюдения строгой иерархии: Элемент -> Тип -> Композитор -> Вложенные элементы. Исправив структуру вашей схемы в соответствии с этими правилами, вы получите корректное дерево объектов в пакете XDTO и сможете полноценно использовать механизмы сериализации платформы.

← На главную