Синтаксис и применение ФасетПеречисленияXS в платформе 1С:Предприятие. Описание и примеры кода.
Полное описание, параметры и ограничения
ФасетПеречисленияXS (XSEnumerationFacet)
ФасетПеречисленияXS (XSEnumerationFacet)
Доступен, начиная с версии 8.1.
Свойства:
Аннотация (Annotation)
Компоненты (Components)
Контейнер (Container)
КорневойКонтейнер (RootContainer)
Схема (Schema)
ТипКомпоненты (ComponentType)
ЭлементDOM (DOMElement)
ЛексическоеЗначение (LexicalValue)
ОпределениеПростогоТипа (SimpleTypeDefinition)
Фиксированный (Fixed)
Значение (Value)
Методы:
КлонироватьКомпоненту (CloneComponent)
ОбновитьЭлементDOM (UpdateDOMElement)
Содержит (Contains)
Конструкторы:
По умолчанию
Доступность:
Сервер, толстый клиент, внешнее соединение.
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Создать ограничения собственного контракта: скидка, описание и статус
Из шести видов новых фасетов строим восемь действующих ограничений для трёх собственных типов XML Schema. Проверяем не только созданные объекты, но и 13 допустимых и недопустимых входных значений через собственную фабрику XDTO.
Где и как запускать
Полный серверный общий модуль УчебныеОграничения своей новой пустой конфигурации УчебныеФасеты85 и полный отдельный модуль формы. В1С не запускался.
Подготовка
НОВАЯ пустая отдельная учебная база точно 8.5.1.1343. Имя конфигурации УчебныеФасеты85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; чужие базы и XML не используются.
Создайте общий модуль УчебныеОграничения: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте полный основной модуль. Создайте свою внешнюю обработку УчебныеФасеты85 с управляемой формой и командой/кнопкой Выполнить, действие Выполнить; отдельный полный модуль формы приведён ниже.
Будущая ручная подготовка: сохранить конфигурацию, Конфигурация → Обновить конфигурацию базы данных (F7), открыть новый собственный клиент и свою обработку. Здесь F7, форма, BSL и XDTO не запускались.
Исходная XML-строка содержит три собственных simpleType без фасетов, только xs:string и xs:decimal. Пространство имён urn:guide:owned-facets — идентификатор, не сетевой адрес. Нет import/include, чтения файлов, настоящей интеграции или изменения метаданных базы.
Процедура ВыполнитьПример() Экспорт
ПроверитьСвойПустойСтенд();
Схема = ПостроитьСвоюИсходнуюСхему();
Скидка = ПолучитьСвоеОпределение(Схема, "Discount");
Описание = ПолучитьСвоеОпределение(Схема, "Description");
Статус = ПолучитьСвоеОпределение(Схема, "Status");
МинимальнаяСкидка = Новый ФасетМинимальногоИсключающегоЗначенияXS;
ПрисоединитьСвойФасет(Скидка, МинимальнаяСкидка, "ФасетМинимальногоИсключающегоЗначенияXS", 0, "0");
МаксимальнаяСкидка = Новый ФасетМаксимальногоИсключающегоЗначенияXS;
ПрисоединитьСвойФасет(Скидка, МаксимальнаяСкидка, "ФасетМаксимальногоИсключающегоЗначенияXS", 1, "1");
МинимальнаяДлина = Новый ФасетМинимальнойДлиныXS;
ПрисоединитьСвойФасет(Описание, МинимальнаяДлина, "ФасетМинимальнойДлиныXS", 3, "3");
МаксимальнаяДлина = Новый ФасетМаксимальнойДлиныXS;
ПрисоединитьСвойФасет(Описание, МаксимальнаяДлина, "ФасетМаксимальнойДлиныXS", 20, "20");
Пробелы = Новый ФасетПробельныхСимволовXS;
ПрисоединитьСвойФасет(Статус, Пробелы, "ФасетПробельныхСимволовXS", ОбработкаПробельныхСимволовXS.Сворачивать, "collapse");
Для Каждого ИмяСтатуса Из СтрРазделить("draft,published,closed", ",") Цикл
ДопустимыйСтатус = Новый ФасетПеречисленияXS;
ПрисоединитьСвойФасет(Статус, ДопустимыйСтатус, "ФасетПеречисленияXS", ИмяСтатуса, ИмяСтатуса);
КонецЦикла;
Если Скидка.Фасеты.Количество() <> 2 Или Описание.Фасеты.Количество() <> 2 Или Статус.Фасеты.Количество() <> 4 Тогда
ВызватьИсключение "Не совпало распределение восьми собственных фасетов";
КонецЕсли;
Скидка.ОбновитьЭлементDOM();
Описание.ОбновитьЭлементDOM();
Статус.ОбновитьЭлементDOM();
Схема.ОбновитьЭлементDOM();
Набор = Новый НаборСхемXML;
Набор.Добавить(Схема);
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Собственная схема должна быть корректна до проверки отдельных значений";
КонецЕсли;
Фабрика = Новый ФабрикаXDTO(Набор);
Случаи = Новый Массив;
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Discount", "0", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Discount", "0.25", Истина, 0.25));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Discount", "1", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Discount", "-0.1", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Description", "Аб", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Description", "ABC", Истина, "ABC"));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Description", "12345678901234567890", Истина, "12345678901234567890"));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Description", "123456789012345678901", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Status", "draft", Истина, "draft"));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Status", " published ", Истина, "published"));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Status", "closed", Истина, "closed"));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Status", "deleted", Ложь, Неопределено));
Случаи.Добавить(Новый Структура("Имя,Вход,Допустимо,Выход", "Status", "PUBLISHED", Ложь, Неопределено));
ПроверитьСвоиСлучаи(Фабрика, Случаи);
КонецПроцедуры
Процедура ПроверитьСвойПустойСтенд()
Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
КонецЕсли;
Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
КонецЕсли;
Источники = Новый Массив;
Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
Для Каждого Источник Из Источники Цикл
Расширения = РасширенияКонфигурации.Получить(, Источник);
Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
ВызватьИсключение "Native список расширений должен иметь тип Массив";
КонецЕсли;
Если Расширения.Количество() <> 0 Тогда
ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
КонецЕсли;
КонецПроцедуры
Функция ПостроитьСвоюИсходнуюСхему()
XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" targetNamespace=""urn:guide:owned-facets"">
|<xs:simpleType name=""Discount""><xs:restriction base=""xs:decimal""/></xs:simpleType>
|<xs:simpleType name=""Description""><xs:restriction base=""xs:string""/></xs:simpleType>
|<xs:simpleType name=""Status""><xs:restriction base=""xs:string""/></xs:simpleType>
|</xs:schema>";
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XSD);
Попытка
Построитель = Новый ПостроительDOM;
DOM = Построитель.Прочитать(Чтение);
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;
Чтение.Закрыть();
ПостроительСхемы = Новый ПостроительСхемXML;
Схема = ПостроительСхемы.СоздатьСхемуXML(DOM.ЭлементДокумента);
Если ТипЗнч(Схема) <> Тип("СхемаXML") Или Схема.ПространствоИмен <> "urn:guide:owned-facets" Тогда
ВызватьИсключение "Не построена своя исходная XML-схема";
КонецЕсли;
Возврат Схема;
КонецФункции
Функция ПолучитьСвоеОпределение(Схема, Имя)
Определение = Схема.ОпределенияТипов.Получить(Имя, "urn:guide:owned-facets");
Если ТипЗнч(Определение) <> Тип("ОпределениеПростогоТипаXS") Или Определение.Имя <> Имя Тогда
ВызватьИсключение "Не найден свой исходный простой тип " + Имя;
КонецЕсли;
Если Определение.Фасеты.Количество() <> 0 Тогда
ВызватьИсключение "В исходном собственном типе не должно быть уже заданных фасетов";
КонецЕсли;
Возврат Определение;
КонецФункции
Процедура ПрисоединитьСвойФасет(Определение, Фасет, ОжидаемыйТип, Значение, Лексическое)
Если ТипЗнч(Фасет) <> Тип(ОжидаемыйТип) Тогда
ВызватьИсключение "Не совпал конкретный тип нового собственного фасета";
КонецЕсли;
Определение.Фасеты.Добавить(Фасет);
Фасет.Значение = Значение;
Фасет.ЛексическоеЗначение = Лексическое;
Если ТипЗнч(Фасет.Значение) <> ТипЗнч(Значение) Или Фасет.Значение <> Значение
Или Фасет.ЛексическоеЗначение <> Лексическое Тогда
ВызватьИсключение "Не совпали типизированное и лексическое значения своего фасета";
КонецЕсли;
Если Фасет.ОпределениеПростогоТипа.Имя <> Определение.Имя
Или Фасет.Схема.ПространствоИмен <> "urn:guide:owned-facets" Тогда
ВызватьИсключение "Фасет должен принадлежать только своему определению и своей схеме";
КонецЕсли;
Фасет.ОбновитьЭлементDOM();
КонецПроцедуры
Процедура ПроверитьСвоиСлучаи(Фабрика, Случаи)
Если Случаи.Количество() <> 13 Тогда
ВызватьИсключение "Ожидалось ровно 13 собственных граничных случаев";
КонецЕсли;
Для Каждого Случай Из Случаи Цикл
ТипМодели = Фабрика.Тип("urn:guide:owned-facets", Случай.Имя);
Если ТипЗнч(ТипМодели) <> Тип("ТипЗначенияXDTO") Тогда
ВызватьИсключение "Не получен свой тип значения XDTO " + Случай.Имя;
КонецЕсли;
Допустимо = Ложь;
ЗначениеМодели = Неопределено;
Попытка
ЗначениеМодели = Фабрика.Создать(ТипМодели, Случай.Вход);
Допустимо = Истина;
Исключение
Сообщить(СтрШаблон("Отклонён собственный пример %1: %2", Случай.Имя, Случай.Вход));
КонецПопытки;
Если Допустимо <> Случай.Допустимо Тогда
ВызватьИсключение СтрШаблон("Не совпало ограничение %1 для [%2]", Случай.Имя, Случай.Вход);
КонецЕсли;
Если Допустимо Тогда
Если ТипЗнч(ЗначениеМодели) <> Тип("ЗначениеXDTO")
Или ТипЗнч(ЗначениеМодели.Значение) <> ТипЗнч(Случай.Выход)
Или ЗначениеМодели.Значение <> Случай.Выход Тогда
ВызватьИсключение "Не совпало полное собственное нормализованное значение";
КонецЕсли;
КонецЕсли;
Сообщить(СтрШаблон("%1 [%2]: допустимо=%3", Случай.Имя, Случай.Вход, Допустимо));
КонецЦикла;
КонецПроцедурыУчебныеФасеты85.Форма
Своя внешняя обработка УчебныеФасеты85 → управляемая Форма → Модуль
Полный отдельный модуль своей формы; не выполнялся.
&НаКлиенте
Процедура Выполнить(Команда)
ВыполнитьНаСервере();
Сообщить("Собственная схема и все 13 граничных случаев проверены");
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
УчебныеОграничения.ВыполнитьПример();
КонецПроцедурыРазбор по шагам
Прочитать собственную строку как DOM и построить СхемаXML. Сразу проверить тип схемы и её пространство имён; получить Discount, Description, Status по имени и тому же URI. У каждого исходного типа должен быть пустой список явных фасетов.
Конструктор создаёт отдельный компонент, но сам по себе не ограничивает данные. ПрисоединитьСвойФасет добавляет его в список именно подготовленного типа, задаёт типизированное и лексическое значения, сверяет их и проверяет владельца. Readonly-свойства Фасеты, Схема и ОпределениеПростогоТипа не присваиваются.
Для Discount создаём два исключающих ограничения 0 и 1. Условие 0 < скидка < 1 относится к доле: 0.25 означает 25 процентов, а не число25. Обе границы недопустимы.
Для Description два компонента задают длины 3 и 20 включительно. Используем короткие простые строки без эмодзи и составных Unicode-символов, чтобы задача не подменялась подсчётом байтов или визуальных знаков.
Для Status фасет пробелов получает настоящее значение enum ОбработкаПробельныхСимволовXS.Сворачивать, лексически collapse. Три отдельных новых ФасетПеречисленияXS задают draft, published, closed. Это перечисление XML-схемы, не менеджер Перечисления конфигурации.
Проверяем распределение восьми фасетов: 2/2/4. Синхронизируем DOM каждого нового компонента, определений и схемы; проверяем набор схем ДО создания фабрики. Фабрика создаётся после добавления ограничений, а не до них.
Только создание значения находится внутри Попытка. Тип модели проверен заранее, а сравнение факта с эталоном — после обработки ошибки. Поэтому исключение собственных проверок не превращается в якобы ожидаемое отклонение входа.
Для всех принятых входов проверяются полный нормализованный результат и его точный тип. Строка с крайними пробелами восстанавливается как published, а скидка0.25 — как число. Все 13 случаев должны совпасть с независимыми эталонами.
Как проверить результат
Будущий результат: 6 входов приняты и 7 отклонены, без исключения о несовпадении. Discount: 0.25 принят; 0, 1, -0.1 отклонены. Description: длины3 и20 приняты, 2 и21 отклонены.
Status: draft, closed и строка с крайними пробелами published приняты; deleted и PUBLISHED отклонены. Нормализованный результат published не содержит крайних пробелов.
Будущий отрицательный контроль: только в вызове для МаксимальнаяДлина замените оба значения 20/"20" на19/"19", не меняя эталон случая с20 символами. Корректная схема будет построена, но положительный случай должен вызвать несовпадение. После опыта восстановите полный исходный модуль.
runtimeVerifiedScenarios=0. Сигнатуры конструкторов, свойства и доступность проверены по установленной справке. Результаты XDTO приведены как ожидаемые: в1С не получены, обратные ссылки владельцев и синхронизация DOM не выполнялись. Пример не отправляет скидки, статусы или описания во внешние системы.
Ожидаемый результат
Шесть разных конструкторов участвуют в одном действующем учебном контракте, проверяемом на всех 13 граничных случаях, а не только в чтении свойств новых пустых объектов.
На что обратить внимание
Новый фасет вне определения типа — ещё не правило проверки. Не пропускайте добавление в Фасеты и не присваивайте readonly-обратные ссылки вручную.
Значение и ЛексическоеЗначение имеют разные типы. У фасета пробелов значение — enum платформы, не строка collapse; у числовых границ в нашей xs:decimal-модели — число, а лексическая запись использует точку.
Свернуть крайние и повторяющиеся XML-пробелы не означает изменить регистр: PUBLISHED не входит в перечисление. Для Description xs:string пробелы этим контрактом не удаляются.
Любая ошибка создания значения будет зафиксирована как отказ, но прежде схема и конкретный тип обязаны пройти подготовительные проверки. Для реального внешнего ввода нужны отдельные диагностика ошибок, ограничения размера и защита XML-парсера; данный урок работает только с собственными постоянными строками.
Схему после построения фабрики не меняем: не рассчитывайте на автоматическое обновление уже построенной модели XDTO. Для другой версии контракта нужен новый проверенный набор и новая фабрика.
Это собственный учебный контракт, не схема Avito и не правила скидок выбранной конфигурации. Нет подтверждения запуска, прав доступа или поведения рабочей базы.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Проверить допустимые статусы и обработку пробелов в XSD
Контракт принимает draft, published, closed и нормализует пробелы правилом collapse. Это не перечисление конфигурации и не изменение статуса реального объявления.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Используйте серверную учебную процедуру и только строковую схему из примера.
Status — наш собственный тип XSD, имена не привязаны к API Авито или к перечислению 1С.
XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema""
| xmlns:g=""urn:guide:limits"" targetNamespace=""urn:guide:limits"">
| <xs:simpleType name=""Price""><xs:restriction base=""xs:decimal"">
| <xs:minInclusive value=""0""/><xs:maxInclusive value=""9999.99""/>
| <xs:totalDigits value=""6""/><xs:fractionDigits value=""2""/>
| </xs:restriction></xs:simpleType>
| <xs:simpleType name=""Discount""><xs:restriction base=""xs:decimal"">
| <xs:minExclusive value=""0""/><xs:maxExclusive value=""1""/>
| </xs:restriction></xs:simpleType>
| <xs:simpleType name=""Status""><xs:restriction base=""xs:string"">
| <xs:whiteSpace value=""collapse""/>
| <xs:enumeration value=""draft""/><xs:enumeration value=""published""/>
| <xs:enumeration value=""closed""/>
| </xs:restriction></xs:simpleType>
| <xs:simpleType name=""Description""><xs:restriction base=""xs:string"">
| <xs:minLength value=""3""/><xs:maxLength value=""20""/>
| </xs:restriction></xs:simpleType>
|</xs:schema>";
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XSD);
Попытка
Документ = Новый ПостроительDOM;
DOM = Документ.Прочитать(Чтение);
Чтение.Закрыть();
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;
Построитель = Новый ПостроительСхемXML;
Схема = Построитель.СоздатьСхемуXML(DOM.ЭлементДокумента);
Если Схема = Неопределено Тогда
ВызватьИсключение "Не построена собственная схема ограничений";
КонецЕсли;
Набор = Новый НаборСхемXML;
Набор.Добавить(Схема);
Если Не Набор.Проверить() Тогда
ВызватьИсключение "Не прошла проверка собственной схемы";
КонецЕсли;
Фабрика = Новый ФабрикаXDTO(Набор);
Определение = Схема.ОпределенияТипов.Получить("Status", "urn:guide:limits");
ТипМодели = Фабрика.Тип("urn:guide:limits", "Status");
Сообщить(Определение.Фасеты.Количество() = 4);
Для Каждого Фасет Из Определение.Фасеты Цикл
Сообщить(Строка(Фасет.ТипКомпоненты) + ": " + Фасет.ЛексическоеЗначение);
Сообщить("Типизированное значение: " + Строка(Фасет.Значение));
Сообщить("Фиксирован в потомках: " + Строка(Фасет.Фиксированный));
Сообщить(Фасет.ОпределениеПростогоТипа.Имя = Определение.Имя);
Сообщить(Фасет.Контейнер <> Неопределено);
Сообщить(Фасет.КорневойКонтейнер <> Неопределено);
Сообщить(Фасет.Схема.ПространствоИмен = "urn:guide:limits");
Сообщить(Фасет.Аннотация = Неопределено);
Сообщить(Фасет.Компоненты.Количество() = 0);
Фасет.ОбновитьЭлементDOM();
Сообщить("XML-тег ограничения: " + Фасет.ЭлементDOM.ИмяЭлемента);
КопияФасета = Фасет.КлонироватьКомпоненту(Истина);
Сообщить(ТипЗнч(КопияФасета) = ТипЗнч(Фасет));
Сообщить(КопияФасета.ЛексическоеЗначение = Фасет.ЛексическоеЗначение);
Сообщить(Не Фасет.Содержит(КопияФасета));
КонецЦикла;
Случаи = Новый Массив;
Случаи.Добавить(Новый Структура("Текст,Ожидается", "draft", Истина));
Случаи.Добавить(Новый Структура("Текст,Ожидается", " published ", Истина));
Случаи.Добавить(Новый Структура("Текст,Ожидается", "closed", Истина));
Случаи.Добавить(Новый Структура("Текст,Ожидается", "deleted", Ложь));
Случаи.Добавить(Новый Структура("Текст,Ожидается", "PUBLISHED", Ложь));
Для Каждого Случай Из Случаи Цикл
Допустимо = Ложь;
Попытка
ЗначениеМодели = Фабрика.Создать(ТипМодели, Случай.Текст);
Допустимо = Истина;
Исключение
Сообщить("Отклонено: " + Случай.Текст + "; "
+ КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
Если Допустимо <> Случай.Ожидается Тогда
ВызватьИсключение "Не совпал результат проверки значения: " + Случай.Текст;
КонецЕсли;
Сообщить(СтрШаблон("%1: допустимо = %2", Случай.Текст, Допустимо));
КонецЦикла;
Нормализованное = Фабрика.Создать(ТипМодели, " published ");
Сообщить(Нормализованное.Значение = "published");Разбор по шагам
Три отдельных фасета перечисления задают допустимые значения одного типа.
whiteSpace collapse удаляет крайние пробелы и сводит последовательности XML-пробелов внутри к одному.
ФасетПробельныхСимволовXS.Значение имеет тип перечисления платформы, тогда как фасеты перечисления здесь имеют строковые значения.
Вход published с крайними пробелами нормализуется и проходит проверку. deleted отсутствует среди допустимых значений.
XML Schema не делает строковые перечисления регистронезависимыми: PUBLISHED не равно published.
Как проверить результат
Четыре фасета: обработка пробелов и три значения перечисления.
draft, closed и published с пробелами принимаются; deleted и PUBLISHED отклоняются.
У нормализованного значения .Значение равно published без крайних пробелов.
Ожидаемый результат
Статус проверен как значение собственного контракта с нормализацией пробелов и чувствительностью к регистру.
На что обратить внимание
СокрЛП и collapse не полностью одинаковы: XSD также определяет обработку внутренних XML-пробелов.
Не превращайте неизвестный статус в draft автоматически: это может скрыть ошибку интеграции.
ФасетПеречисленияXS не является менеджером Перечисления конфигурации.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.