DOM → компонент XS и адресное удаление своей схемы из временного набора

Учебные задачи

Восстанавливаем настоящее собственное определение Sku из DOM, проверяем совпадение с моделью XDTO и отказ не-XSD структуры. Удаляем схему только из отдельного собственного memory-набора по ее реальному UUID namespace.

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

Полный серверный общий модуль собственной файловой ИБ; native ПостроительСхемXML только сервер/толстый клиент/внешнее соединение. Runtime0.

Подготовка

  1. Не открывайте УНФ, КА2, БП или УТ: создайте отдельную новую пустую файловую ИБ на платформе ровно8.5.1.1343. Пример не предназначен для production и не меняет конфигурации пользователя.

  2. В Конфигураторе установите имя корня конфигурации УчебныеСкалярныеXDTO85, управляемое приложение и совместимость Не использовать. В конфигурации не должно быть справочников, документов, регистров, общих реквизитов, фоновых заданий, подписок или внешних источников.

  3. Не устанавливайте расширения ни в базу, ни в сеанс. Полный ПроверитьСвойПустойСтенд в каждом основном модуле проверяет все три native-источника расширений, отсутствие активной транзакции.

  4. Создайте общий модуль УчебныеXDTO85: СерверИстина, ВызовСервераЛожь, ГлобальныйЛожь, Клиент(управляемое приложение)Ложь, Клиент(обычное приложение)Ложь, ВнешнееСоединениеЛожь, ПривилегированныйЛожь. Поместите весь основной код этого урока в этот пустой модуль.

  5. Создайте обработку УчебныеXDTO85 с собственной основной управляемой формой. Добавьте команду Выполнить, обработчик Выполнить и кнопку на форме. Поместите полный вспомогательный модуль формы из этого урока; он передаёт только итоговую строку, не фабрику/DOM/XDTO-объект между клиентом и сервером.

  6. Уроки самостоятельны: для следующего урока замените весь собственный общий модуль соответствующим полным основным кодом. Одновременное склеивание модулей с одинаковым ВыполнитьПример85 запрещено.

  7. UUID создается локально для каждого опыта. URI urn:guide:xdto-scalars85:<UUID> и дополнительный URI с :extra — имена пространств, не URL. Схема, DOM, фабрика и XML создаются лишь в памяти: нет import/include, DTD, чтения файлов, сети, обращения к базам или глобальной ФабрикаXDTO конфигурации.

  8. Собственная XSD полностью включена в код: Sku — строка ровно4символа с прописной латинской буквой и3цифрами; SkuList — список Sku; QtyOrSku — union positiveInteger/Sku; Envelope — открытая wildcard-структура; Closed — закрытая структура.

  9. Обновите только свою учебную конфигурацию базы данных. Запустите собственную обработку в тонком управляемом клиенте; API построения схем выполняется на серверном контексте файловой ИБ, а не в клиентском модуле.

  10. Это подготовленный пример, проверенный статически и по установленной справке. Фактических запусков 1С здесь0; если ручной тест выдает исключение, сохраните его текст и не убирайте защитные проверки ради продолжения.

Функция ВыполнитьПример85() Экспорт
    Опыт = ПодготовитьСвойКонтракт85();
    Элементы = Опыт.ДокументСхемы.ЭлементДокумента.ПолучитьЭлементыПоИмени("http://www.w3.org/2001/XMLSchema", "simpleType");
    Если ТипЗнч(Элементы) <> Тип("СписокЭлементовDOM") Или Элементы.Количество() <> 3 Тогда
        ВызватьИсключение "Наша реальная DOM-схема должна содержать ровно три simpleType";
    КонецЕсли;
    DOMАртикула = Элементы.Элемент(0);
    Если DOMАртикула.ПолучитьАтрибут("name") <> "Sku" Тогда
        ВызватьИсключение "Порядок нашей собственной схемы подменен";
    КонецЕсли;
    Построитель = Новый ПостроительСхемXML;
    Компонента = Построитель.СоздатьКомпонентуXS(DOMАртикула, Опыт.Схема);
    Если ТипЗнч(Компонента) <> Тип("ОпределениеПростогоТипаXS") Или Компонента.Имя <> "Sku" Тогда
        ВызватьИсключение "DOM-декларация должна разобрать реальное собственное определение простого типа";
    КонецЕсли;
    ТипАртикула = Опыт.Фабрика.Тип(Опыт.URI, Компонента.Имя);
    Артикул = Опыт.Фабрика.Создать(ТипАртикула, "A001");
    Если Артикул.Значение <> "A001" Тогда
        ВызватьИсключение "Собственный восстановленный компонент не соответствует модели фабрики";
    КонецЕсли;
    ЧтениеЧужойСтруктуры = Новый ЧтениеXML;
    ЧтениеЧужойСтруктуры.УстановитьСтроку("<notASchema/>" );
    Попытка
        Дерево = Новый ПостроительDOM;
        НеСхема = Дерево.Прочитать(ЧтениеЧужойСтруктуры);
    Исключение
        ОшибкаDOM = ОписаниеОшибки();
        Попытка
            ЧтениеЧужойСтруктуры.Закрыть();
        Исключение
            ВызватьИсключение ОшибкаDOM + Символы.ПС + "Закрытие DOM: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаDOM;
    КонецПопытки;
    ЧтениеЧужойСтруктуры.Закрыть();
    Если Построитель.СоздатьКомпонентуXS(НеСхема.ЭлементДокумента, Опыт.Схема) <> Неопределено Тогда
        ВызватьИсключение "Посторонняя структура own-XML не должна давать компонент схемы";
    КонецЕсли;
    ВременныйНабор = Новый НаборСхемXML;
    ВременныйНабор.Добавить(Опыт.Схема);
    Если ВременныйНабор.Количество() <> 1 Или ВременныйНабор.Получить(Опыт.URI) <> Опыт.Схема Тогда
        ВызватьИсключение "Удалять можно лишь собственную подтвержденную URI-схему в своем отдельном наборе";
    КонецЕсли;
    ВременныйНабор.Удалить(Опыт.URI);
    Если ВременныйНабор.Количество() <> 0 Или Опыт.Набор.Количество() <> 1 Тогда
        ВызватьИсключение "Удаление должно опустошить только отдельный свой временный набор";
    КонецЕсли;
    ЕщеАртикул = Опыт.Фабрика.Создать(ТипАртикула, "B002");
    Если ЕщеАртикул.Значение <> "B002" Тогда
        ВызватьИсключение "Наш основной набор и отдельная фабрика должны оставаться пригодными";
    КонецЕсли;
    Возврат "UUID " + Опыт.UUIDОпыта + ": own DOM Sku → ОпределениеПростогоТипаXS → SKU A001; не-XSD дает Неопределено; свой временный набор 1→0, основной1, SKU B002";
КонецФункции

Процедура ПроверитьСвойПустойСтенд()
    Если Метаданные.Справочники.Количество() <> 0 Или Метаданные.Документы.Количество() <> 0 Или Метаданные.Перечисления.Количество() <> 0 Или Метаданные.РегистрыСведений.Количество() <> 0 Или Метаданные.РегистрыНакопления.Количество() <> 0 Или Метаданные.РегистрыБухгалтерии.Количество() <> 0 Или Метаданные.РегистрыРасчета.Количество() <> 0 Или Метаданные.ПланыВидовХарактеристик.Количество() <> 0 Или Метаданные.ПланыВидовРасчета.Количество() <> 0 Или Метаданные.ПланыСчетов.Количество() <> 0 Или Метаданные.ПланыОбмена.Количество() <> 0 Или Метаданные.Последовательности.Количество() <> 0 Или Метаданные.БизнесПроцессы.Количество() <> 0 Или Метаданные.Задачи.Количество() <> 0 Или Метаданные.ОбщиеРеквизиты.Количество() <> 0 Или Метаданные.ПодпискиНаСобытия.Количество() <> 0 Или Метаданные.РегламентныеЗадания.Количество() <> 0 Или Метаданные.ВнешниеИсточникиДанных.Количество() <> 0 Тогда
        ВызватьИсключение "Нужен только свой новый пустой учебный стенд";
    КонецЕсли;
    Если Метаданные.ЕстьИзмененияРасширениямиКонфигурации() Тогда
        ВызватьИсключение "Свой сеанс не должен изменяться расширениями";
    КонецЕсли;
    Источники = Новый Массив;
    Источники.Добавить(ИсточникРасширенийКонфигурации.БазаДанных);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансАктивные);
    Источники.Добавить(ИсточникРасширенийКонфигурации.СеансОтключенные);
    Для Каждого Источник Из Источники Цикл
        Расширения = РасширенияКонфигурации.Получить(, Источник);
        Если ТипЗнч(Расширения) <> Тип("Массив") Тогда
            ВызватьИсключение "Native список расширений должен иметь тип Массив";
        КонецЕсли;
        Если Расширения.Количество() <> 0 Тогда
            ВызватьИсключение "В своём новом стенде нет расширений базы или сеанса";
        КонецЕсли;
    КонецЦикла;
    Если ТранзакцияАктивна() Тогда
        ВызватьИсключение "Чужая или вложенная активная транзакция не допускается";
    КонецЕсли;
КонецПроцедуры

Функция ПодготовитьСвойКонтракт85()
    ПроверитьСвойПустойСтенд();
    UUIDОпыта = Строка(Новый УникальныйИдентификатор);
    Если UUIDОпыта = "00000000-0000-0000-0000-000000000000" Тогда
        ВызватьИсключение "Нужен собственный ненулевой UUID опыта";
    КонецЕсли;
    URI = "urn:guide:xdto-scalars85:" + UUIDОпыта;
    XSD = "<xs:schema xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:g=""urn:guide:xdto-scalars85:__UUID__"" targetNamespace=""urn:guide:xdto-scalars85:__UUID__"" elementFormDefault=""qualified"">
    |<xs:simpleType name=""Sku""><xs:restriction base=""xs:string""><xs:length value=""4""/><xs:pattern value=""[A-Z][0-9]{3}""/></xs:restriction></xs:simpleType>
    |<xs:simpleType name=""SkuList""><xs:list itemType=""g:Sku""/></xs:simpleType>
    |<xs:simpleType name=""QtyOrSku""><xs:union memberTypes=""xs:positiveInteger g:Sku""/></xs:simpleType>
    |<xs:complexType name=""Envelope""><xs:sequence><xs:any namespace=""##other"" processContents=""lax"" minOccurs=""0"" maxOccurs=""unbounded""/></xs:sequence><xs:attribute name=""code"" type=""g:Sku"" use=""required""/><xs:attribute name=""status"" type=""xs:string"" default=""draft""/><xs:anyAttribute namespace=""##other"" processContents=""lax""/></xs:complexType>
    |<xs:complexType name=""Closed""><xs:attribute name=""code"" type=""g:Sku"" use=""required""/></xs:complexType>
    |<xs:element name=""sku"" type=""g:Sku""/><xs:element name=""skuList"" type=""g:SkuList""/><xs:element name=""qtyOrSku"" type=""g:QtyOrSku""/><xs:element name=""envelope"" type=""g:Envelope""/><xs:element name=""closed"" type=""g:Closed""/>
    |</xs:schema>";
    XSD = СтрЗаменить(XSD, "__UUID__", UUIDОпыта);
    ЧтениеСхемы = Новый ЧтениеXML;
    ЧтениеСхемы.УстановитьСтроку(XSD);
    Попытка
        Дерево = Новый ПостроительDOM;
        ДокументСхемы = Дерево.Прочитать(ЧтениеСхемы);
    Исключение
        ОшибкаСхемы = ОписаниеОшибки();
        Попытка
            ЧтениеСхемы.Закрыть();
        Исключение
            ВызватьИсключение ОшибкаСхемы + Символы.ПС + "Закрытие XML: " + ОписаниеОшибки();
        КонецПопытки;
        ВызватьИсключение ОшибкаСхемы;
    КонецПопытки;
    ЧтениеСхемы.Закрыть();
    ПостроительСхем = Новый ПостроительСхемXML;
    Схема = ПостроительСхем.СоздатьСхемуXML(ДокументСхемы.ЭлементДокумента);
    Набор = Новый НаборСхемXML;
    Набор.Добавить(Схема);
    Если Набор.Количество() <> 1 Или Не Набор.Проверить() Тогда
        ВызватьИсключение "Не подтверждена единственная собственная схема без внешних ссылок";
    КонецЕсли;
    Фабрика = Новый ФабрикаXDTO(Набор);
    Для Каждого Имя Из СтрРазделить("Sku,SkuList,QtyOrSku,Envelope,Closed", ",") Цикл
        Если Фабрика.Тип(URI, Имя) = Неопределено Тогда
            ВызватьИсключение "Собственный тип схемы не создан: " + Имя;
        КонецЕсли;
    КонецЦикла;
    Возврат Новый Структура("UUIDОпыта,URI,XSD,ДокументСхемы,Схема,Набор,Фабрика",
        UUIDОпыта, URI, XSD, ДокументСхемы, Схема, Набор, Фабрика);
КонецФункции
Полный модуль собственной управляемой формы

Обработка УчебныеXDTO85: полный модуль собственной управляемой формы

Управляемая форма обработки УчебныеXDTO85: единственная команда и кнопка Выполнить; общий модуль только серверный.

&НаКлиенте
Процедура Выполнить(Команда)
    Результат = ВыполнитьНаСервере();
    Сообщить(Результат);
КонецПроцедуры

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

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

  1. Полная авторская схема уже прочитана в настоящий ДокументDOM, построена в СхемаXML и проверена в единственном наборе.

  2. ПолучитьЭлементыПоИмени с namespace схем XML дает ровно3simpleType. Первый реальный DOM-элемент имеет name=Sku; не используются неизвестные компоненты.

  3. СоздатьКомпонентуXS принимает именно этот ЭлементDOM и собственную СхемаXML как контекст. Полученный объект проверяется как ОпределениеПростогоТипаXS с собственным именем Sku.

  4. Не вставляйте восстановленный компонент обратно в ту же схему: определение Sku там уже есть, дублирование имени не нужно. Здесь это независимый разбор конкретной декларации.

  5. Имя восстановленного определения используем для поиска своего XDTO-типа и создания реального A001, подтверждая связь DOM/XS/XDTO.

  6. Другую собственную строку <notASchema/> читаем в отдельный DOM. Native СоздатьКомпонентуXS должен вернуть Неопределено, поскольку структура элемента не соответствует компоненту схемы.

  7. Создаем отдельный временный НаборСхемXML, добавляем ровно свою схему и сверяем Получить(свойURI) с тем же экземпляром.

  8. Удалить получает native URI строки, не индекс и не объект схемы. Удаляем лишь из временного набора: там1→0, основной набор остается1.

  9. Создаем новый B002 основной фабрикой и проверяем результат. Удаление из набора не означает удаление XSD-файла, пакета конфигурации или чего-либо в базе.

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

  1. Компонент создается из собственного реального DOM с реальным контекстом, не произвольного готового объекта; тип/имя подтверждены.

  2. Посторонняя структура собственного DOM дает native Неопределено, не придуманное false.

  3. До Удалить временный набор имеет ровно1собственную схему; после0, основной1.

  4. После очистки отдельного набора основная фабрика создает B002. Все удаления исключительно в памяти; runtime0.

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

Ожидаемый ручной результат: own DOM Sku → ОпределениеПростогоТипаXS → A001; не-XSD → Неопределено; временный набор1→0, основной1 и B002. Фактической 1С-проверки еще нет.

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

  1. СоздатьКомпонентуXS создает компонент из DOM; он не является автоматическим добавлением в Содержимое схемы. Авторская схема уже содержит нужное определение.

  2. Метод Удалить принимает пространство имен. Урок не изображает его файловым удалением и не изменяет общий рабочий набор.

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

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

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

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

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