ОпределениеПростогоТипаXS.Фасеты

Свойства · Facets

Тип: СписокКомпонентXS. Список компонентов-фасетов, принадлежащих данному определению простого типа.

Полное описание, параметры и ограничения

ОпределениеПростогоТипаXS.Фасеты (XSSimpleTypeDefinition.Facets)

ОпределениеПростогоТипаXS (XSSimpleTypeDefinition)

Фасеты (Facets)

Доступен, начиная с версии 8.1.

Использование:
Только чтение.
Описание:
Тип: СписокКомпонентXS.
Список компонентов-фасетов, принадлежащих данному определению простого типа.
Доступность:

Сервер, толстый клиент, внешнее соединение.

Использование в версии:

Доступен, начиная с версии 8.1.

Методическая информация

Практические примеры

Создать ограничения собственного контракта: скидка, описание и статус

Из шести видов новых фасетов строим восемь действующих ограничений для трёх собственных типов XML Schema. Проверяем не только созданные объекты, но и 13 допустимых и недопустимых входных значений через собственную фабрику XDTO.

Где и как запускать

Полный серверный общий модуль УчебныеОграничения своей новой пустой конфигурации УчебныеФасеты85 и полный отдельный модуль формы. В1С не запускался.

Подготовка

  1. НОВАЯ пустая отдельная учебная база точно 8.5.1.1343. Имя конфигурации УчебныеФасеты85, совместимость Не использовать. Нет бизнес-объектов, расширений, подписок и фоновых заданий; чужие базы и XML не используются.

  2. Создайте общий модуль УчебныеОграничения: Сервер=Да, Вызов сервера=Да, Клиент=Нет, Глобальный=Нет, Привилегированный=Нет. Вставьте полный основной модуль. Создайте свою внешнюю обработку УчебныеФасеты85 с управляемой формой и командой/кнопкой Выполнить, действие Выполнить; отдельный полный модуль формы приведён ниже.

  3. Будущая ручная подготовка: сохранить конфигурацию, Конфигурация → Обновить конфигурацию базы данных (F7), открыть новый собственный клиент и свою обработку. Здесь F7, форма, BSL и XDTO не запускались.

  4. Исходная 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 граничных случаев проверены");
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере()
    УчебныеОграничения.ВыполнитьПример();
КонецПроцедуры

Разбор по шагам

  1. Прочитать собственную строку как DOM и построить СхемаXML. Сразу проверить тип схемы и её пространство имён; получить Discount, Description, Status по имени и тому же URI. У каждого исходного типа должен быть пустой список явных фасетов.

  2. Конструктор создаёт отдельный компонент, но сам по себе не ограничивает данные. ПрисоединитьСвойФасет добавляет его в список именно подготовленного типа, задаёт типизированное и лексическое значения, сверяет их и проверяет владельца. Readonly-свойства Фасеты, Схема и ОпределениеПростогоТипа не присваиваются.

  3. Для Discount создаём два исключающих ограничения 0 и 1. Условие 0 < скидка < 1 относится к доле: 0.25 означает 25 процентов, а не число25. Обе границы недопустимы.

  4. Для Description два компонента задают длины 3 и 20 включительно. Используем короткие простые строки без эмодзи и составных Unicode-символов, чтобы задача не подменялась подсчётом байтов или визуальных знаков.

  5. Для Status фасет пробелов получает настоящее значение enum ОбработкаПробельныхСимволовXS.Сворачивать, лексически collapse. Три отдельных новых ФасетПеречисленияXS задают draft, published, closed. Это перечисление XML-схемы, не менеджер Перечисления конфигурации.

  6. Проверяем распределение восьми фасетов: 2/2/4. Синхронизируем DOM каждого нового компонента, определений и схемы; проверяем набор схем ДО создания фабрики. Фабрика создаётся после добавления ограничений, а не до них.

  7. Только создание значения находится внутри Попытка. Тип модели проверен заранее, а сравнение факта с эталоном — после обработки ошибки. Поэтому исключение собственных проверок не превращается в якобы ожидаемое отклонение входа.

  8. Для всех принятых входов проверяются полный нормализованный результат и его точный тип. Строка с крайними пробелами восстанавливается как published, а скидка0.25 — как число. Все 13 случаев должны совпасть с независимыми эталонами.

Как проверить результат

  1. Будущий результат: 6 входов приняты и 7 отклонены, без исключения о несовпадении. Discount: 0.25 принят; 0, 1, -0.1 отклонены. Description: длины3 и20 приняты, 2 и21 отклонены.

  2. Status: draft, closed и строка с крайними пробелами published приняты; deleted и PUBLISHED отклонены. Нормализованный результат published не содержит крайних пробелов.

  3. Будущий отрицательный контроль: только в вызове для МаксимальнаяДлина замените оба значения 20/"20" на19/"19", не меняя эталон случая с20 символами. Корректная схема будет построена, но положительный случай должен вызвать несовпадение. После опыта восстановите полный исходный модуль.

  4. runtimeVerifiedScenarios=0. Сигнатуры конструкторов, свойства и доступность проверены по установленной справке. Результаты XDTO приведены как ожидаемые: в1С не получены, обратные ссылки владельцев и синхронизация DOM не выполнялись. Пример не отправляет скидки, статусы или описания во внешние системы.

Ожидаемый результат

Шесть разных конструкторов участвуют в одном действующем учебном контракте, проверяемом на всех 13 граничных случаях, а не только в чтении свойств новых пустых объектов.

На что обратить внимание

  1. Новый фасет вне определения типа — ещё не правило проверки. Не пропускайте добавление в Фасеты и не присваивайте readonly-обратные ссылки вручную.

  2. Значение и ЛексическоеЗначение имеют разные типы. У фасета пробелов значение — enum платформы, не строка collapse; у числовых границ в нашей xs:decimal-модели — число, а лексическая запись использует точку.

  3. Свернуть крайние и повторяющиеся XML-пробелы не означает изменить регистр: PUBLISHED не входит в перечисление. Для Description xs:string пробелы этим контрактом не удаляются.

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

  5. Схему после построения фабрики не меняем: не рассчитывайте на автоматическое обновление уже построенной модели XDTO. Для другой версии контракта нужен новый проверенный набор и новая фабрика.

  6. Это собственный учебный контракт, не схема Avito и не правила скидок выбранной конфигурации. Нет подтверждения запуска, прав доступа или поведения рабочей базы.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

XML-счёт: собственные копии фасетов, группы и уникальный артикул4→5→4

Полный memory workflow для новичка: две собственные строки → native XS model → настоящие собственные definition constructors/typed clones/guarded Set → свежая схема → actual XML validation и сумма1050.

Где и как запускать

Полный серверный общий модуль своей новой пустой FileCF .1343; вызывается собственной управляемой формой толстого клиента. XS model/validation не переносится в thin/web. Actual runtime0.

Подготовка

  1. Задача: собственный XML-счёт BOOK3×250=750 и TEA_2×150=300. Проверить артикулам длину4, допустимые символы и уникальность, сменить только независимую live политику4→5→4, получить настоящие числовые поля DOM и сумму1050. Это не импорт рабочей базы.

  2. Вручную создайте НОВУЮ пустую файловую ИБ платформы8.5.1.1343 строго по пути C:\1C85_OwnXSInvoice\7b57b5b8-5742-4d10-9bf0-30a78abc871f\Base. Если путь уже занят, остановитесь. UUID каталога — учебная метка пути, не UUID ИБ. Здесь новая ИБ/каталог/роль/пользователь фактически не создавались.

  3. Конфигуратор: новая конфигурация УчебнаяПолитикаСчетаXS85, основной режим УправляемоеПриложение, совместимость НеИспользовать. Ровно один общий модуль, одна управляемая общая форма и одна роль УчебныйАдминистратор85. Прикладных объектов/общих макетов/хранилищ/параметров сеанса/расширений нет.

  4. В своей роли разрешите Администрирование, запуск толстого управляемого клиента и доступ к своей форме. Создайте ровно одного собственного реального пользователя УчебныйАдминистратор85, войдите им в один сеанс. Native GetUsers требует административного права. Код сравнивает настоящий UUID текущего пользователя с единственным native пользователем, не требует placeholder.

  5. Общие → Общие модули → УчебныйСчетXS85: Глобальный Нет; Сервер Да; оба клиента Нет; Внешнее соединение Нет; Вызов сервера Нет; Привилегированный Нет; повторное использование возвращаемых значений НеИспользовать. Вставьте целиком CODE. moduleOwner=ОбщийМодуль; экспорт только ВыполнитьСвойУрок85, не helpers с чужой схемой.

  6. Общие → Общие формы → ПолитикаСчетаXS85: управляемая форма без основного реквизита. Протокол85 — Строка неограниченной длины, многострочное поле только просмотра. Остановка85 — Булево, начальное значение Ложь, не редактируется. Команда Проверить85 с Действие=Проверить85; одна кнопка Команда=Проверить85. Вставьте FORM целиком.

  7. Корень своей конфигурации → Модуль управляемого приложения: вставьте APPLICATION целиком. Настоящее native ПриНачалеРаботыСистемы() без аргументов открывает только свою форму. Не вызывайте событие вручную. После будущего ручного обновления своей ИБ откройте толстый управляемый клиент и нажмите свою кнопку ровно один раз.

  8. ИсходнаяСхема85 и Счет85 содержат полные собственные тексты. Нет targetNamespace, внешних DTD/сущностей/import/include/schemaLocation, дисковых путей XML, загрузки URL или сетевого контракта. URI xs — имя встроенного языка схем, не инструкция загрузки. Helpers не экспортируются; не подменяйте их внешними входами.

  9. ПостроительDOM.Прочитать(ЧтениеXML) возвращает настоящий XML DOM; ПостроительСхемXML.СоздатьСхемуXML может вернуть Неопределено, поэтому Type guard обязателен. Два экземпляра Original/Live создаются отдельным чтением собственного текста, не объявляются независимыми только по имени переменной.

  10. Каркас:5 глобальных компонентов,2 собственных определения типов Sku/Item,1 invoice,1 Amounts sequence из quantity/price,1 Identity с обязательным sku. Facets ровно2, их индексы находятся по настоящим Type, а не фиксируются0/1. Нет неоднозначного РазрешитьОпределениеТипа.

  11. Новые ОпределениеГруппыМоделиXS/ОпределениеГруппыАтрибутовXS — native конструкторы без аргументов. В live заменяется только фактически найденная own definition с тем же именем; копируются actual model/attribute-use компоненты. Native Contains и Get до/после Set подтверждают exact list state. Unknown/nonempty native default новой группы не очищается — fail-stop.

  12. Новый ОпределениеОграниченияИдентичностиXS и два Новый ОпределенияXPathXS без аргументов создают настоящие Unique/selector item/field @sku. Поля и ОграниченияИдентичности — readonly ссылки на изменяемые native списки: заменять сами свойства нельзя. No-namespace XPath нужен именно своему no-targetNamespace XML.

  13. ФасетДлиныXS/ФасетОбразцаXS.КлонироватьКомпоненту(Истина) возвращает union типов XS: каждый actual Type проверен. Contains(Аннотация) проверяет принадлежность компонента, НЕ соответствие строки регулярному выражению. Содержит не получает BOOK/TEA_; lexical matching выполняет настоящая schema validation.

  14. Native default не обещан пустым. Readback проверяет пустые fresh own collections перед Add, свои count/types/containment до Set. Clone annotation принадлежит clone и не original; если эффект shared/неожиданный — отказ до дальнейших замен. Точный сериализованный собственный DOM-снимок и отдельные typed original readbacks подтверждают этот оригинал, не независимость произвольных внешних схем.

  15. Readonly Фасеты/Содержимое не присваиваются. Native Set(index,component) меняет только детально подтверждённый own список. Value длины — Число4/5, Value образца — Строка [A-Z_]{4}/[A-Z_]{5}; перед сменой обратно обе текущие live величины и ownership проверены. Нет слепого rollback после неизвестной ошибки.

  16. После изменения выполняются UpdateDOM, native сериализация в Строку и НОВОЕ чтение schema model из фактического текущего текста. Затем НОВЫЙ НаборСхемXML/Add/Validate. Использовать старый cached проверенный набор после смены модели запрещено. Fresh reread повторяет facets/identity XPath и полный каркас.

  17. ПараметрыЧтенияXML readonly. Используется реальный конструктор11 optional аргументов: ValidationType задаётся в четвёртой позиции, не setter. XMLReader.SetString получает именно свежий validated SchemaSet третьим аргументом, Read доводится доEOF. Набор.Проверить проверяет схему; чтение проверяет XML-экземпляр — это разные действия.

  18. Положительный счёт прочитан из actual DOM:2 item, настоящий sku, quantity/price, qty5/total1050 вычислены из текста узлов, а не подставлены. При length5 контроль BOOKS/TEA_X также даёт1050; length4 BOOK/TEA_ тогда обязан вызвать native отказ. После подтверждённого собственного возврата4 счёт снова читается.

  19. Каждый отрицательный XML сначала читается без schema validation вне catch, чтобы не маскировать синтаксическую ошибку. Положительный контроль той же актуальной схемы выполняется до/после узкого try, в котором только native SetString/Read. Constructors/schema setup/copy/type/readback failures не классифицируются как ожидаемый отказ. Диагностика берётся фактически, точный текст/номер ошибки не угадывается.

  20. Наблюдение native отказа и двух успешных контролей — учебный ручной протокол, не универсальный классификатор всех ошибок/OOM. Изучите фактическую диагностику отрицательных случаев; если она не про проверяемую XSD, остановитесь, не считайте произвольное исключение успехом. RuntimeVerified=False: здесь 1С/compile/DB/UI/файлы XML/сеть/печать/provisioning/backup0.

  21. При неизвестном частичном отказе client и server оставляют Остановка85=True, rethrow; клиент отдельно устанавливает local flag, поскольку серверное изменение может не синхронизироваться при исключении. Нет автоматического retry, cleanup чужой схемы или обещания атомарности memory/UI действий. Закройте свою форму и разберите причину.

Процедура ПроверитьСвойСтенд85()
    Если СтрокаСоединенияИнформационнойБазы() <> "File=""C:\1C85_OwnXSInvoice\7b57b5b8-5742-4d10-9bf0-30a78abc871f\Base"";" Тогда
        ВызватьИсключение "Только собственная новая учебная файловая ИБ";
    КонецЕсли;
    Если Метаданные.РежимСовместимости <> Метаданные.СвойстваОбъектов.РежимСовместимости.НеИспользовать Тогда
        ВызватьИсключение "Не совпали своя конфигурация и точная платформа";
    КонецЕсли;
    Если Метаданные.ОбщиеМодули.Количество() <> 1 Или Метаданные.ОбщиеМодули.Найти("УчебныйСчетXS85") = Неопределено
        Или Метаданные.ОбщиеФормы.Количество() <> 1 Или Метаданные.ОбщиеФормы.Найти("ПолитикаСчетаXS85") = Неопределено
        Или Метаданные.Роли.Количество() <> 1 Или Метаданные.Роли.Найти("УчебныйАдминистратор85") = Неопределено Тогда
        ВызватьИсключение "Нужны только свои общий модуль, форма и роль";
    КонецЕсли;
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0
        Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0
        Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0
        Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0
        Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0
        Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0
        Или Метаданные.Обработки.Количество() <> 0 Или Метаданные.Отчеты.Количество() <> 0
        Или Метаданные.Константы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0
        Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Или Метаданные.ХранилищаНастроек.Количество() <> 0
        Или Метаданные.ОбщиеМакеты.Количество() <> 0 Или Метаданные.ПараметрыСеанса.Количество() <> 0 Тогда
        ВызватьИсключение "Учебная прикладная схема должна быть пустой";
    КонецЕсли;
    Если РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.БазаДанных).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансАктивные).Количество() <> 0
        Или РасширенияКонфигурации.Получить(, ИсточникРасширенийКонфигурации.СеансОтключенные).Количество() <> 0 Тогда
        ВызватьИсключение "Урок не допускает расширений";
    КонецЕсли;
    Текущий = ПользователиИнформационнойБазы.ТекущийПользователь();
    Пользователи = ПользователиИнформационнойБазы.ПолучитьПользователей();
    Если Текущий = Неопределено Или Пользователи.Количество() <> 1 Тогда
        ВызватьИсключение "Нужен единственный собственный реальный пользователь ИБ";
    КонецЕсли;
    Если Текущий.Имя <> "УчебныйАдминистратор85" Или Пользователи[0].УникальныйИдентификатор <> Текущий.УникальныйИдентификатор Тогда
        ВызватьИсключение "Не совпал реальный UUID пользователя своей ИБ";
    КонецЕсли;
КонецПроцедуры

Функция ИсходнаяСхема85()
    Возврат "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" version=""1.0"">
    |<xs:simpleType name=""Sku""><xs:restriction base=""xs:string"">
    |<xs:length value=""4""><xs:annotation><xs:documentation>own-length-four</xs:documentation></xs:annotation></xs:length>
    |<xs:pattern value=""[A-Z_]{4}""><xs:annotation><xs:documentation>own-uppercase-or-underscore</xs:documentation></xs:annotation></xs:pattern>
    |</xs:restriction></xs:simpleType>
    |<xs:group name=""Amounts""><xs:sequence><xs:element name=""quantity"" type=""xs:positiveInteger""/><xs:element name=""price"" type=""xs:decimal""/></xs:sequence></xs:group>
    |<xs:attributeGroup name=""Identity""><xs:attribute name=""sku"" type=""Sku"" use=""required""/></xs:attributeGroup>
    |<xs:complexType name=""Item""><xs:sequence><xs:group ref=""Amounts""/></xs:sequence><xs:attributeGroup ref=""Identity""/></xs:complexType>
    |<xs:element name=""invoice""><xs:complexType><xs:sequence><xs:element name=""item"" type=""Item"" minOccurs=""2"" maxOccurs=""2""/></xs:sequence></xs:complexType></xs:element>
    |</xs:schema>";
КонецФункции

Функция Счет85(ПервыйАртикул, ВторойАртикул)
    Если (ПервыйАртикул <> "BOOK" И ПервыйАртикул <> "BOOKS")
        Или (ВторойАртикул <> "TEA_" И ВторойАртикул <> "TEAX" И ВторойАртикул <> "TEA_X" И ВторойАртикул <> "BOOK" И ВторойАртикул <> "tea_") Тогда
        ВызватьИсключение "Артикулы только из собственных фиксированных учебных вариантов, не внешний ввод";
    КонецЕсли;
    Возврат "<invoice><item sku=""" + ПервыйАртикул + """><quantity>3</quantity><price>250</price></item><item sku=""" + ВторойАртикул + """><quantity>2</quantity><price>150</price></item></invoice>";
КонецФункции

Функция ПараметрыЧтения85(Проверять)
    Возврат Новый ПараметрыЧтенияXML("1.0", "ru", ПробельныеСимволыXML.ПоУмолчанию,
        ?(Проверять, ТипПроверкиXML.СхемаXML, ТипПроверкиXML.НетПроверки), Истина, Истина, Ложь, Ложь, Истина, Ложь, Ложь);
КонецФункции

Функция ПрочитатьСвойDOM85(ТекстXML, Набор = Неопределено)
    Если ТипЗнч(ТекстXML) <> Тип("Строка") Или СтрДлина(ТекстXML) > 12000
        Или СтрНайти(ВРег(ТекстXML), "<!DOCTYPE") <> 0 Или СтрНайти(ВРег(ТекстXML), "<!ENTITY") <> 0 Тогда
        ВызватьИсключение "Только свои ограниченные строки без DTD и сущностей";
    КонецЕсли;
    Чтение = Новый ЧтениеXML;
    Параметры = ПараметрыЧтения85(Набор <> Неопределено);
    Построитель = Новый ПостроительDOM;
    Попытка
        Чтение.УстановитьСтроку(ТекстXML, Параметры, Набор);
        Документ = Построитель.Прочитать(Чтение);
        Пока Чтение.Прочитать() Цикл
        КонецЦикла;
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Документ) <> Тип("ДокументDOM") Или Документ.ОпределениеТипаДокумента <> Неопределено Тогда
        ВызватьИсключение "Нужен собственный XML DOM без определения типа документа";
    КонецЕсли;
    Возврат Документ;
КонецФункции

Функция ПостроитьСвоюСхему85(ТекстXSD)
    Документ = ПрочитатьСвойDOM85(ТекстXSD);
    ПостроительСхем = Новый ПостроительСхемXML;
    Схема = ПостроительСхем.СоздатьСхемуXML(Документ.ЭлементДокумента);
    Если ТипЗнч(Схема) <> Тип("СхемаXML") Тогда
        ВызватьИсключение "Native builder не вернул схему XML";
    КонецЕсли;
    ПроверитьКаркас85(Схема);
    Возврат Схема;
КонецФункции

Процедура ПроверитьКаркас85(Схема)
    Если ТипЗнч(Схема) <> Тип("СхемаXML") Или Схема.ПространствоИмен <> ""
        Или Схема.Директивы.Количество() <> 0 Или Схема.Содержимое.Количество() <> 5
        Или Схема.ОпределенияТипов.Количество() <> 2 Или Схема.ОбъявленияЭлементов.Количество() <> 1
        Или Схема.ОпределенияГруппМоделей.Количество() <> 1 Или Схема.ОпределенияГруппАтрибутов.Количество() <> 1
        Или Схема.ОбъявленияАтрибутов.Количество() <> 0 Или Схема.ОбъявленияНотаций.Количество() <> 0 Тогда
        ВызватьИсключение "Не совпал полный собственный каркас без импортов и include";
    КонецЕсли;
    Артикул = Схема.ОпределенияТипов.Получить("Sku", "");
    Модель = Схема.ОпределенияГруппМоделей.Получить("Amounts", "");
    Атрибуты = Схема.ОпределенияГруппАтрибутов.Получить("Identity", "");
    Корень = Схема.ОбъявленияЭлементов.Получить("invoice", "");
    Если ТипЗнч(Артикул) <> Тип("ОпределениеПростогоТипаXS") Или ТипЗнч(Модель) <> Тип("ОпределениеГруппыМоделиXS")
        Или ТипЗнч(Атрибуты) <> Тип("ОпределениеГруппыАтрибутовXS") Или ТипЗнч(Корень) <> Тип("ОбъявлениеЭлементаXS") Тогда
        ВызватьИсключение "Нужны реальные собственные определения, не строки имён";
    КонецЕсли;
    Если Артикул.Имя <> "Sku" Или Артикул.Фасеты.Количество() <> 2 Или Модель.Имя <> "Amounts" Или Модель.ЭтоСсылка
        Или ТипЗнч(Модель.ГруппаМодели) <> Тип("ГруппаМоделиXS") Или Модель.ГруппаМодели.ВидГруппы <> ВидГруппыМоделиXS.Последовательность
        Или Модель.ГруппаМодели.Фрагменты.Количество() <> 2 Или Атрибуты.Имя <> "Identity" Или Атрибуты.ЭтоСсылка
        Или Атрибуты.Содержимое.Количество() <> 1 Или Корень.Имя <> "invoice" Тогда
        ВызватьИсключение "Не совпали собственные поля групп и артикула";
    КонецЕсли;
КонецПроцедуры

Функция НайтиСвоиФасеты85(Схема)
    Артикул = Схема.ОпределенияТипов.Получить("Sku", "");
    Если ТипЗнч(Артикул) <> Тип("ОпределениеПростогоТипаXS") Или Артикул.Фасеты.Количество() <> 2 Тогда
        ВызватьИсключение "Не найдены два собственных фасета Sku";
    КонецЕсли;
    Фасеты = Артикул.Фасеты;
    Длина = Неопределено;
    Образец = Неопределено;
    ИндексДлины = -1;
    ИндексОбразца = -1;
    Для Индекс = 0 По Фасеты.Количество() - 1 Цикл
        Компонент = Фасеты.Получить(Индекс);
        Если ТипЗнч(Компонент) = Тип("ФасетДлиныXS") И Длина = Неопределено Тогда
            Длина = Компонент;
            ИндексДлины = Индекс;
        ИначеЕсли ТипЗнч(Компонент) = Тип("ФасетОбразцаXS") И Образец = Неопределено Тогда
            Образец = Компонент;
            ИндексОбразца = Индекс;
        Иначе
            ВызватьИсключение "Лишний, повторный или неизвестный фасет";
        КонецЕсли;
    КонецЦикла;
    Если Длина = Неопределено Или Образец = Неопределено Или ИндексДлины < 0 Или ИндексОбразца < 0
        Или Не Фасеты.Содержит(Длина) Или Не Фасеты.Содержит(Образец) Тогда
        ВызватьИсключение "Не подтверждена собственная коллекция фасетов";
    КонецЕсли;
    Возврат Новый Структура("Коллекция,Длина,Образец,ИндексДлины,ИндексОбразца", Фасеты, Длина, Образец, ИндексДлины, ИндексОбразца);
КонецФункции

Процедура ЗаменитьСвойКомпонент85(Содержимое, Старый, НовыйКомпонент)
    Если ТипЗнч(Содержимое) <> Тип("СписокКомпонентXS") Или Содержимое.Количество() <> 5
        Или Не Содержимое.Содержит(Старый) Или Содержимое.Содержит(НовыйКомпонент) Тогда
        ВызватьИсключение "Замена только точного своего компонента, не чужая коллекция";
    КонецЕсли;
    НайденныйИндекс = -1;
    Для Индекс = 0 По Содержимое.Количество() - 1 Цикл
        Если Содержимое.Получить(Индекс) = Старый Тогда
            Если НайденныйИндекс <> -1 Тогда
                ВызватьИсключение "Повторный собственный компонент";
            КонецЕсли;
            НайденныйИндекс = Индекс;
        КонецЕсли;
    КонецЦикла;
    Если НайденныйИндекс < 0 Тогда
        ВызватьИсключение "Реальный индекс замены не найден";
    КонецЕсли;
    Содержимое.Установить(НайденныйИндекс, НовыйКомпонент);
    Если Содержимое.Количество() <> 5 Или Содержимое.Содержит(Старый) Или Не Содержимое.Содержит(НовыйКомпонент)
        Или Содержимое.Получить(НайденныйИндекс) <> НовыйКомпонент Тогда
        ВызватьИсключение "Не подтвердился native readback после замены";
    КонецЕсли;
КонецПроцедуры

Процедура УстановитьСвоиОпределения85(Живая)
    ПроверитьКаркас85(Живая);
    ИсходнаяГруппа = Живая.ОпределенияГруппМоделей.Получить("Amounts", "");
    КопияМодели = ИсходнаяГруппа.ГруппаМодели.КлонироватьКомпоненту(Истина);
    Если ТипЗнч(КопияМодели) <> Тип("ГруппаМоделиXS") Или КопияМодели.Фрагменты.Количество() <> 2 Тогда
        ВызватьИсключение "Нет типизированной рекурсивной копии своей модели";
    КонецЕсли;
    НоваяГруппа = Новый ОпределениеГруппыМоделиXS;
    НоваяГруппа.Имя = "Amounts";
    НоваяГруппа.ГруппаМодели = КопияМодели;
    ЗаменитьСвойКомпонент85(Живая.Содержимое, ИсходнаяГруппа, НоваяГруппа);
    ИсходныеАтрибуты = Живая.ОпределенияГруппАтрибутов.Получить("Identity", "");
    Использование = ИсходныеАтрибуты.Содержимое.Получить(0);
    Если ТипЗнч(Использование) <> Тип("ИспользованиеАтрибутаXS") Тогда
        ВызватьИсключение "Нет собственного использования обязательного атрибута sku";
    КонецЕсли;
    КопияИспользования = Использование.КлонироватьКомпоненту(Истина);
    Если ТипЗнч(КопияИспользования) <> Тип("ИспользованиеАтрибутаXS") Тогда
        ВызватьИсключение "Native clone не вернул использование атрибута";
    КонецЕсли;
    НовыеАтрибуты = Новый ОпределениеГруппыАтрибутовXS;
    Если НовыеАтрибуты.Содержимое.Количество() <> 0 Тогда
        ВызватьИсключение "Неподтверждённый native default новой группы: не очищаем";
    КонецЕсли;
    НовыеАтрибуты.Имя = "Identity";
    НовыеАтрибуты.Содержимое.Добавить(КопияИспользования);
    ЗаменитьСвойКомпонент85(Живая.Содержимое, ИсходныеАтрибуты, НовыеАтрибуты);
    Корень = Живая.ОбъявленияЭлементов.Получить("invoice", "");
    Если Корень.ОграниченияИдентичности.Количество() <> 0 Тогда
        ВызватьИсключение "У своего исходного invoice не должно быть готовых ограничений идентичности";
    КонецЕсли;
    Ограничение = Новый ОпределениеОграниченияИдентичностиXS;
    Если Ограничение.Поля.Количество() <> 0 Тогда
        ВызватьИсключение "Неподтверждённое начальное поле native constraint: не очищаем";
    КонецЕсли;
    Селектор = Новый ОпределенияXPathXS;
    Селектор.Вариант = ВариантXPathXS.Селектор;
    Селектор.XPath = "item";
    Поле = Новый ОпределенияXPathXS;
    Поле.Вариант = ВариантXPathXS.Поле;
    Поле.XPath = "@sku";
    Ограничение.Имя = "OwnUniqueSku";
    Ограничение.Категория = КатегорияОграниченияИдентичностиXS.Уникальность;
    Ограничение.Селектор = Селектор;
    Ограничение.Поля.Добавить(Поле);
    Корень.ОграниченияИдентичности.Добавить(Ограничение);
    НоваяГруппа.ОбновитьЭлементDOM();
    НовыеАтрибуты.ОбновитьЭлементDOM();
    Ограничение.ОбновитьЭлементDOM();
    Корень.ОбновитьЭлементDOM();
    Живая.ОбновитьЭлементDOM();
    Если НоваяГруппа.Имя <> "Amounts" Или НоваяГруппа.ГруппаМодели <> КопияМодели
        Или НовыеАтрибуты.Имя <> "Identity" Или НовыеАтрибуты.Содержимое.Количество() <> 1
        Или НовыеАтрибуты.Содержимое.Получить(0) <> КопияИспользования
        Или Корень.ОграниченияИдентичности.Количество() <> 1 Или Корень.ОграниченияИдентичности.Получить(0) <> Ограничение
        Или Ограничение.Селектор <> Селектор Или Ограничение.Поля.Количество() <> 1 Или Ограничение.Поля.Получить(0) <> Поле
        Или Селектор.XPath <> "item" Или Поле.XPath <> "@sku" Тогда
        ВызватьИсключение "Не подтверждён полный собственный live binding";
    КонецЕсли;
КонецПроцедуры

Функция УстановитьСвоиКопииФасетов85(Оригинал, Живая)
    Исходные = НайтиСвоиФасеты85(Оригинал);
    Длина = Исходные.Длина;
    Образец = Исходные.Образец;
    Если Длина.Значение <> 4 Или Образец.Значение <> "[A-Z_]{4}"
        Или ТипЗнч(Длина.Аннотация) <> Тип("АннотацияXS") Или ТипЗнч(Образец.Аннотация) <> Тип("АннотацияXS")
        Или Не Длина.Содержит(Длина.Аннотация) Или Не Образец.Содержит(Образец.Аннотация) Тогда
        ВызватьИсключение "Нет собственных исходных фасетов и принадлежащих им аннотаций";
    КонецЕсли;
    КопияДлины = Длина.КлонироватьКомпоненту(Истина);
    КопияОбразца = Образец.КлонироватьКомпоненту(Истина);
    Если ТипЗнч(КопияДлины) <> Тип("ФасетДлиныXS") Или ТипЗнч(КопияОбразца) <> Тип("ФасетОбразцаXS")
        Или ТипЗнч(КопияДлины.Аннотация) <> Тип("АннотацияXS") Или ТипЗнч(КопияОбразца.Аннотация) <> Тип("АннотацияXS") Тогда
        ВызватьИсключение "Native clone вернул неожиданный тип";
    КонецЕсли;
    Если Не КопияДлины.Содержит(КопияДлины.Аннотация) Или Не КопияОбразца.Содержит(КопияОбразца.Аннотация)
        Или Длина.Содержит(КопияДлины.Аннотация) Или Образец.Содержит(КопияОбразца.Аннотация) Тогда
        ВызватьИсключение "Независимость этих двух копий аннотаций не подтверждена";
    КонецЕсли;
    Текущие = НайтиСвоиФасеты85(Живая);
    Фасеты = Текущие.Коллекция;
    Если Фасеты.Содержит(КопияДлины) Или Фасеты.Содержит(КопияОбразца)
        Или Фасеты.Получить(Текущие.ИндексДлины) <> Текущие.Длина Или Фасеты.Получить(Текущие.ИндексОбразца) <> Текущие.Образец Тогда
        ВызватьИсключение "Исходное собственное состояние live list не подтверждено";
    КонецЕсли;
    Фасеты.Установить(Текущие.ИндексДлины, КопияДлины);
    Фасеты.Установить(Текущие.ИндексОбразца, КопияОбразца);
    Если Фасеты.Количество() <> 2 Или Не Фасеты.Содержит(КопияДлины) Или Не Фасеты.Содержит(КопияОбразца)
        Или Фасеты.Содержит(Текущие.Длина) Или Фасеты.Содержит(Текущие.Образец)
        Или Фасеты.Получить(Текущие.ИндексДлины) <> КопияДлины Или Фасеты.Получить(Текущие.ИндексОбразца) <> КопияОбразца Тогда
        ВызватьИсключение "Native Set не подтвердил точную замену своих двух фасетов";
    КонецЕсли;
    Возврат НайтиСвоиФасеты85(Живая);
КонецФункции

Функция ТекстСвоейМодели85(Схема)
    Схема.ОбновитьЭлементDOM();
    Если ТипЗнч(Схема.ЭлементDOM) <> Тип("ЭлементDOM") Тогда
        ВызватьИсключение "Нет синхронизированного native элемента модели";
    КонецЕсли;
    Запись = Новый ЗаписьXML;
    Запись.УстановитьСтроку();
    ПисательDOM = Новый ЗаписьDOM;
    ПисательDOM.Записать(Схема.ЭлементDOM, Запись);
    Возврат Запись.Закрыть();
КонецФункции

Функция СобратьСвежийНабор85(Живая, ДлинаАртикула, ОбразецАртикула, СУникальностью)
    Текущие = НайтиСвоиФасеты85(Живая);
    Если Текущие.Длина.Значение <> ДлинаАртикула Или Текущие.Образец.Значение <> ОбразецАртикула Тогда
        ВызватьИсключение "Ожидаемые изменения live политики не подтверждены";
    КонецЕсли;
    Текущие.Длина.ОбновитьЭлементDOM();
    Текущие.Образец.ОбновитьЭлементDOM();
    Свежая = ПостроитьСвоюСхему85(ТекстСвоейМодели85(Живая));
    Прочитанные = НайтиСвоиФасеты85(Свежая);
    Если Прочитанные.Длина.Значение <> ДлинаАртикула Или Прочитанные.Образец.Значение <> ОбразецАртикула Тогда
        ВызватьИсключение "Native reread не увидел live изменения, старый cached набор не используем";
    КонецЕсли;
    Корень = Свежая.ОбъявленияЭлементов.Получить("invoice", "");
    Если Корень.ОграниченияИдентичности.Количество() <> ?(СУникальностью, 1, 0) Тогда
        ВызватьИсключение "Не подтвердилось собственное ограничение в новом фактическом DOM";
    КонецЕсли;
    Если СУникальностью Тогда
        Ограничение = Корень.ОграниченияИдентичности.Получить(0);
        Если ТипЗнч(Ограничение) <> Тип("ОпределениеОграниченияИдентичностиXS") Или Ограничение.Имя <> "OwnUniqueSku"
            Или Ограничение.Категория <> КатегорияОграниченияИдентичностиXS.Уникальность
            Или Ограничение.Селектор.Вариант <> ВариантXPathXS.Селектор Или Ограничение.Селектор.XPath <> "item"
            Или Ограничение.Поля.Количество() <> 1 Или Ограничение.Поля.Получить(0).Вариант <> ВариантXPathXS.Поле
            Или Ограничение.Поля.Получить(0).XPath <> "@sku" Тогда
            ВызватьИсключение "Новый compiled исходник не содержит свои реальные XPath";
        КонецЕсли;
    КонецЕсли;
    Набор = Новый НаборСхемXML;
    Набор.Добавить(Свежая);
    Если Набор.Количество() <> 1 Или Не Набор.Проверить() Тогда
        ВызватьИсключение "Свежий собственный набор схем не прошёл native Validate";
    КонецЕсли;
    Возврат Набор;
КонецФункции

Функция ПрочитатьРеальныйСчет85(ТекстXML, Набор, ПервыйАртикул, ВторойАртикул)
    Документ = ПрочитатьСвойDOM85(ТекстXML, Набор);
    Корень = Документ.ЭлементДокумента;
    Если Корень.ИмяУзла <> "invoice" Или Корень.ДочерниеУзлы.Количество() <> 2 Тогда
        ВызватьИсключение "Реальный XML должен содержать ровно две строки своего счёта";
    КонецЕсли;
    ВсегоКоличество = 0;
    ВсегоСумма = 0;
    Для Индекс = 0 По 1 Цикл
        СтрокаСчета = Корень.ДочерниеУзлы.Элемент(Индекс);
        Если ТипЗнч(СтрокаСчета) <> Тип("ЭлементDOM") Или СтрокаСчета.ИмяУзла <> "item"
            Или СтрокаСчета.ПолучитьАтрибут("sku") <> ?(Индекс = 0, ПервыйАртикул, ВторойАртикул)
            Или СтрокаСчета.ДочерниеУзлы.Количество() <> 2 Тогда
            ВызватьИсключение "Не совпала целая фактическая строка своего XML";
        КонецЕсли;
        УзелКоличество = СтрокаСчета.ДочерниеУзлы.Элемент(0);
        УзелЦена = СтрокаСчета.ДочерниеУзлы.Элемент(1);
        Если ТипЗнч(УзелКоличество) <> Тип("ЭлементDOM") Или ТипЗнч(УзелЦена) <> Тип("ЭлементDOM")
            Или УзелКоличество.ИмяУзла <> "quantity" Или УзелЦена.ИмяУзла <> "price" Тогда
            ВызватьИсключение "Реальная модель Amounts не дала свои числовые поля";
        КонецЕсли;
        Количество = Число(УзелКоличество.ТекстовоеСодержимое);
        Цена = Число(УзелЦена.ТекстовоеСодержимое);
        Если Количество <> ?(Индекс = 0, 3, 2) Или Цена <> ?(Индекс = 0, 250, 150) Тогда
            ВызватьИсключение "В XML прочитаны другие числа";
        КонецЕсли;
        ВсегоКоличество = ВсегоКоличество + Количество;
        ВсегоСумма = ВсегоСумма + Количество * Цена;
    КонецЦикла;
    Если ВсегоКоличество <> 5 Или ВсегоСумма <> 1050 Тогда
        ВызватьИсключение "Не подтвердились суммы из настоящих native DOM значений";
    КонецЕсли;
    Возврат Новый Структура("Количество,Сумма", ВсегоКоличество, ВсегоСумма);
КонецФункции

Функция ОжидатьNativeОтказ85(Набор, Плохой, Контроль, ПервыйКонтроль, ВторойКонтроль)
    ПрочитатьСвойDOM85(Плохой);
    ПрочитатьРеальныйСчет85(Контроль, Набор, ПервыйКонтроль, ВторойКонтроль);
    Чтение = Новый ЧтениеXML;
    Параметры = ПараметрыЧтения85(Истина);
    Отказ = Ложь;
    Диагностика = "";
    Попытка
        Чтение.УстановитьСтроку(Плохой, Параметры, Набор);
        Пока Чтение.Прочитать() Цикл
        КонецЦикла;
    Исключение
        Отказ = Истина;
        Диагностика = ОписаниеОшибки();
    КонецПопытки;
    Чтение.Закрыть();
    Если Не Отказ Или Диагностика = "" Тогда
        ВызватьИсключение "Ожидался наблюдаемый native отказ для своего отрицательного XML";
    КонецЕсли;
    ПрочитатьРеальныйСчет85(Контроль, Набор, ПервыйКонтроль, ВторойКонтроль);
    Возврат Диагностика;
КонецФункции

Процедура ПроверитьОригинал85(Оригинал, Снимок)
    ПроверитьКаркас85(Оригинал);
    Исходные = НайтиСвоиФасеты85(Оригинал);
    Если Исходные.Длина.Значение <> 4 Или Исходные.Образец.Значение <> "[A-Z_]{4}"
        Или Оригинал.ОбъявленияЭлементов.Получить("invoice", "").ОграниченияИдентичности.Количество() <> 0
        Или ТекстСвоейМодели85(Оригинал) <> Снимок Тогда
        ВызватьИсключение "Изменился исходный собственный typed модельный или DOM снимок";
    КонецЕсли;
    НаборОригинала = СобратьСвежийНабор85(Оригинал, 4, "[A-Z_]{4}", Ложь);
    ПрочитатьРеальныйСчет85(Счет85("BOOK", "TEA_"), НаборОригинала, "BOOK", "TEA_");
КонецПроцедуры

Функция ВыполнитьСвойУрок85() Экспорт
    ПроверитьСвойСтенд85();
    Оригинал = ПостроитьСвоюСхему85(ИсходнаяСхема85());
    Снимок = ТекстСвоейМодели85(Оригинал);
    Живая = ПостроитьСвоюСхему85(ИсходнаяСхема85());
    ПроверитьОригинал85(Оригинал, Снимок);
    УстановитьСвоиОпределения85(Живая);
    Свои = УстановитьСвоиКопииФасетов85(Оригинал, Живая);
    Длина = Свои.Длина;
    Образец = Свои.Образец;
    Набор = СобратьСвежийНабор85(Живая, 4, "[A-Z_]{4}", Истина);
    До = ПрочитатьРеальныйСчет85(Счет85("BOOK", "TEA_"), Набор, "BOOK", "TEA_");
    Дубликат = ОжидатьNativeОтказ85(Набор, Счет85("BOOK", "BOOK"), Счет85("BOOK", "TEA_"), "BOOK", "TEA_");
    ЛишнийСимвол = ОжидатьNativeОтказ85(Набор, Счет85("BOOKS", "TEA_"), Счет85("BOOK", "TEA_"), "BOOK", "TEA_");
    НижнийРегистр = ОжидатьNativeОтказ85(Набор, Счет85("BOOK", "tea_"), Счет85("BOOK", "TEA_"), "BOOK", "TEA_");
    ПроверитьОригинал85(Оригинал, Снимок);
    Если Длина.Значение <> 4 Или Образец.Значение <> "[A-Z_]{4}" Тогда
        ВызватьИсключение "Нельзя менять неподтверждённое текущее состояние своей live политики";
    КонецЕсли;
    Длина.Значение = 5;
    Образец.Значение = "[A-Z_]{5}";
    НаборПяти = СобратьСвежийНабор85(Живая, 5, "[A-Z_]{5}", Истина);
    ДлинаПять = ОжидатьNativeОтказ85(НаборПяти, Счет85("BOOK", "TEA_"), Счет85("BOOKS", "TEA_X"), "BOOKS", "TEA_X");
    ПроверитьОригинал85(Оригинал, Снимок);
    Если Длина.Значение <> 5 Или Образец.Значение <> "[A-Z_]{5}"
        Или Не Свои.Коллекция.Содержит(Длина) Или Не Свои.Коллекция.Содержит(Образец) Тогда
        ВызватьИсключение "Не подтверждено своё состояние5; никакого слепого восстановления";
    КонецЕсли;
    Длина.Значение = 4;
    Образец.Значение = "[A-Z_]{4}";
    ФинальныйНабор = СобратьСвежийНабор85(Живая, 4, "[A-Z_]{4}", Истина);
    После = ПрочитатьРеальныйСчет85(Счет85("BOOK", "TEA_"), ФинальныйНабор, "BOOK", "TEA_");
    ПроверитьОригинал85(Оригинал, Снимок);
    Если До.Количество <> После.Количество Или До.Сумма <> После.Сумма Тогда
        ВызватьИсключение "Реальный счёт изменился после собственной подтверждённой смены политики";
    КонецЕсли;
    Возврат "Ожидаемый ручной протокол: native счёт2строки, количество5, сумма1050; политика4→5→4."
        + Символы.ПС + "Дубликат: " + Дубликат + Символы.ПС + "Артикул5 при длине4: " + ЛишнийСимвол
        + Символы.ПС + "Нижний регистр: " + НижнийРегистр + Символы.ПС + "Артикул4 при длине5: " + ДлинаПять;
КонецФункции
Полный модуль своей управляемой общей формы

Общие → Общие формы → ПолитикаСчетаXS85 → Модуль

Windows thick managed client/server own form; sticky guard at both boundaries.

&НаКлиенте
Процедура Проверить85(Команда)
#Если ТолстыйКлиентУправляемоеПриложение Тогда
    Если Остановка85 Или ТипЗнч(Команда) <> Тип("КомандаФормы") Или Команда <> Команды.Проверить85 Тогда
        ВызватьИсключение "Своя форма остановлена или команда не принадлежит ей";
    КонецЕсли;
    Попытка
        ПроверитьНаСервере85();
    Исключение
        Остановка85 = Истина;
        Протокол85 = "Отказ: закройте форму. Никакого автоматического повтора или отката.";
        ВызватьИсключение;
    КонецПопытки;
#Иначе
    ВызватьИсключение "Урок только для своего толстого управляемого клиента";
#КонецЕсли
КонецПроцедуры

&НаСервере
Процедура ПроверитьНаСервере85()
    Если Остановка85 Тогда
        ВызватьИсключение "Серверная граница запрещает повтор после частичной ошибки";
    КонецЕсли;
    Попытка
        Протокол85 = УчебныйСчетXS85.ВыполнитьСвойУрок85();
    Исключение
        Остановка85 = Истина;
        ВызватьИсключение;
    КонецПопытки;
КонецПроцедуры
Полный модуль своего управляемого приложения

Своя конфигурация → Модуль управляемого приложения

Windows thick managed own application, real OnStart0.

Процедура ПриНачалеРаботыСистемы()
#Если ТолстыйКлиентУправляемоеПриложение Тогда
    ОткрытьФорму("ОбщаяФорма.ПолитикаСчетаXS85");
#Иначе
    ВызватьИсключение "Учебный сценарий только для своего толстого управляемого клиента";
#КонецЕсли
КонецПроцедуры

Разбор по шагам

  1. Подготовьте только свой exact FileCF/пользователя/модули/управляемую форму. Запуск вручную один раз своей настоящей кнопкой.

  2. Создайте Original и Live отдельными native чтениями полного своего XSD. Зафиксируйте original typed/DOM snapshot и positive1050.

  3. Постройте новые Amounts/Identity definition, замените только соответствующие own components по найденным индексам. Добавьте свой настоящий Unique constraint selector item/field @sku.

  4. Клонируйте настоящие annotated facets, проверьте actual types/containment/отсутствие shared annotation, затем native Set только в exact live список.

  5. Постройте fresh SchemaSet из актуального native DOM. Реальные BOOK/TEA_ дают qty5/total1050; duplicateBOOK, SKU5 и lower-case вызывают наблюдаемый native отказ при двух successful controls.

  6. Только подтверждённые live clones переведите на length5/pattern5. Контроль BOOKS/TEA_X успешен1050, оригинальный4char счёт rejected. Original всё ещё прежний.

  7. При exact own state5 и подтверждённом containment верните4. Ещё один fresh model/set даёт actual1050; original snapshot остаётся точным.

Как проверить результат

  1. Будущая ручная positive проверка: реальные2 DOM item, quantity3/2, price250/150, totalQuantity5, totalSum1050 до/после.

  2. Live Components5 и Facets2 не меняют количество при Set; новые definition реально присутствуют, старые отсутствуют. Fresh native XPath Unique присутствует ровно1 только в Live.

  3. Четыре наблюдаемых native отказа: duplicateBOOK, BOOKS при length4, tea_, BOOK/TEA_ при length5. Каждый bad XML синтаксически проверен отдельно, каждый актуальный good control успешен до/после.

  4. В own отрицательной проверке подмените index/type/arity/readonly/clone binding/unknown default: явный fail-stop до продолжения, не условный пропуск или подставленный исходный объект.

  5. Статические/native-source проверки не подтверждают реальный запуск, compile/XSD engine behavior, default emptiness, конкретную диагностику или GUI rendering.

Ожидаемый результат

Ожидаемый будущий ручной результат: actual XML-счёт2строки, qty5/total1050, live политика4→5→4,4 наблюдаемых отрицательных проверки, исходная модель без изменений. RuntimeVerified=False; actual1C/compile/DB/UI/XMLfiles/network/backup0.

На что обратить внимание

  1. Contains принимает XS компонент, а не артикул и не регулярное выражение. Лексические ограничения реально применяет XMLReader с ТипПроверкиXML.СхемаXML.

  2. Новый НаборСхемXML после изменения нельзя заменить старым checkedSet. UpdateDOM/native serialization/fresh parsing/readback фиксируют фактическую текущую модель.

  3. Readonly child collections не равны readonly элементам: Фасеты/Поля/ОграниченияИдентичности/Содержимое не присваиваются, используются только documented own methods.

  4. Нельзя выдумывать параметры нулевых конструкторов/возвращаемый объект у Set/UpdateDOM/Add. Broad clone return требует проверки actual Type.

  5. Не используются DTD/DOM entity maps, undocumented canonicalization, неоднозначные ResolveTypeDefinition/IsSubset/HTMLCompare/DeleteCell; count10 не расширяется ими.

  6. Свои literal XML/XSD и контролируемые аргументы не заменяются внешним вводом. Это учебный in-memory контракт, не безопасный универсальный XML-парсер/импорт/производственная миграция.

  7. Наблюдаемая ошибка XML без документированного errorcode не является универсальным доказательством именно XSD нарушения; будущую фактическую диагностику нужно читать. Здесь runtime0.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.