При работе с интеграциями через XDTO-пакеты разработчики 1С часто сталкиваются с ситуацией, когда XSD-схема содержит множество необязательных полей в рамках одной последовательности xs:sequence. Основная сложность заключается в том, чтобы итоговый XML-файл содержал только те узлы, которые действительно заполнены данными, не включая пустые теги или значения по умолчанию. Рассмотрим подробно, как управлять составом элементов в объекте XDTO, основываясь на правилах работы платформы 1С.
Проанализируем пример схемы, представленный в вопросе. Чтобы ускорить проектирование, можно использовать автоматическое формирование XSD-пакета, а сейчас мы видим описание типа, содержащего последовательность элементов:
<xs:element name="purchaseFeatures" minOccurs="0">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element name="isBudgetUnionState" type="xs:boolean" fixed="true" minOccurs="0"></xs:element>
<xs:element name="contractConclusionOnSt83Ch2" type="xs:boolean" fixed="true" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Здесь критически важными являются два атрибута: minOccurs="0" и fixed="true". Первый означает, что элемент может отсутствовать в XML-документе. Второй жестко фиксирует значение: если тег присутствует, он обязан содержать true. Наша задача — научиться программно определять, какой из этих тегов попадет в выгрузку, а какой будет полностью проигнорирован сериализатором.
Разберем, как 1С работает с объектами XDTO "под капотом". Когда мы создаем новый объект через ФабрикаXDTO.Создать(), платформа инициализирует структуру согласно типу. Однако, если свойство помечено как minOccurs="0", оно изначально находится в состоянии "Не установлено".
Рассмотрим важный нюанс: при просмотре объекта XDTO в отладчике мы можем увидеть, что поле типа boolean отображается как Ложь, а числовое поле как 0. Это часто вводит разработчиков в заблуждение. На самом деле, это лишь визуальное представление значения по умолчанию. Пока вы явно не присвоили свойству значение в коде, оно считается отсутствующим для выгрузки.
Выясним, как добиться того, чтобы в блоке purchaseFeatures заполнился только один элемент. Это актуально не только для XDTO, но и когда выполняется экспорт любых документов в JSON. Самый простой и правильный способ — просто не обращаться к тому свойству, которое должно отсутствовать.
Посмотрим на пример кода:
// Создаем объект на основании типа из пакета
ТипОсобенности = ФабрикаXDTO.Тип("http://www.example.org/purchase", "purchaseFeatures");
Особенности = ФабрикаXDTO.Создать(ТипОсобенности);
// Заполняем только первый элемент
Особенности.isBudgetUnionState = Истина;
// К свойству contractConclusionOnSt83Ch2 мы не обращаемся.
// Несмотря на то, что в отладчике оно может выглядеть как "Ложь",
// в итоговый XML оно не попадет, так как minOccurs="0".
Бывают ситуации, когда объект XDTO заполняется автоматически (например, при чтении из базы или через универсальные механизмы), и нам нужно программно "удалить" уже установленное значение, чтобы тег исчез из XML. Для этого в языке 1С предусмотрен метод Вычеркнуть() (или Unset() в англоязычном варианте).
Проанализируем ситуацию, когда свойство было заполнено по ошибке:
// Допустим, значение было установлено ранее
Особенности.contractConclusionOnSt83Ch2 = Истина;
// Чтобы элемент полностью исчез из XML-структуры:
Особенности.Вычеркнуть("contractConclusionOnSt83Ch2");
После вызова этого метода состояние свойства снова станет "Не установлено". Это гарантирует, что при записи через ЗаписатьXML() данный узел будет пропущен.
Чтобы не гадать, попадет ли элемент в выгрузку, мы можем воспользоваться методом Установлено(). Похожий принцип применяется, когда выполняется проверка на заполненность обязательных полей в структурах данных, что особенно полезно при написании сложных обработок выгрузки.
Если Особенности.Установлено("isBudgetUnionState") Тогда
Сообщить("Элемент будет присутствовать в XML");
Иначе
Сообщить("Элемент пропущен");
КонецЕсли;
Важно: Присвоение значения Неопределено не всегда эквивалентно методу Вычеркнуть(). Если в схеме указано nillable="true", установка в Неопределено может привести к генерации тега с атрибутом xsi:nil="true".
Поскольку в нашей схеме используется конструктор xs:sequence, порядок элементов при их физической записи в XML строго определен схемой. Однако в коде 1С вы можете устанавливать свойства в любом порядке. Платформа самостоятельно упорядочит их в соответствии с XSD-пакетом при сериализации. Если вы заполните только второй элемент последовательности, пропустив первый, это не будет ошибкой — 1С просто сформирует XML, начиная сразу со второго тега, так как первый является необязательным.
minOccurs="0".Вычеркнуть(): если нужно гарантированно удалить свойство из уже существующего объекта XDTO.nillable: помните, что отсутствие тега (minOccurs) и пустой тег с признаком "null" (nillable) — это разные вещи в XML.fixed: если вы все же решили заполнить элемент, значение должно строго соответствовать тому, что указано в схеме (в данном случае Истина).Следуя этим правилам, мы обеспечим корректную работу с веб-сервисами и файловым обменом, исключая ошибки валидации на принимающей стороне, связанные с лишними или некорректно заполненными полями.