КомментарийHTML.Атрибуты

Свойства · Attributes

Тип: КоллекцияАтрибутовHTML. Содержит коллекцию атрибутов узла. Коллекция атрибутов доступна только для узла Element. Узел Атрибуты Атрибут - Неопределено; Комментарий - Неопределено; Документ - Неопределено; ФрагментДокумента - Неопределено; ОпределениеТипаДокумента - Неопределено; Элемент - КоллекцияАтрибутовHTML; Текст - Неопределено.

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

КомментарийHTML.Атрибуты (HTMLComment.Attributes)

КомментарийHTML (HTMLComment)

Атрибуты (Attributes)

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

Использование:
Только чтение.
Описание:
Тип: КоллекцияАтрибутовHTML.
Содержит коллекцию атрибутов узла. Коллекция атрибутов доступна только для узла Element.
Узел Атрибуты
Атрибут - Неопределено;

Комментарий - Неопределено;

Документ - Неопределено;

ФрагментДокумента - Неопределено;

ОпределениеТипаДокумента - Неопределено;

Элемент - КоллекцияАтрибутовHTML;

Текст - Неопределено.

Доступность:

Тонкий клиент, мобильный клиент, сервер, толстый клиент, внешнее соединение, мобильное приложение (клиент), мобильное приложение (сервер), мобильный автономный сервер.

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

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

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

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

Изменить три отделённые HTML-копии и сохранить настоящие оригиналы

Настоящие атрибут, текст и комментарий из своей строки копируются с проверкой реальных типов, паспорта, отдельных границ и пользовательских отметок. Меняем только копии на B-02, повторно читаем неизменные оригиналы A-01 и вычисляем сумму отметок 6.

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

Сервер; полный неглобальный непривилегированный общий модуль HTMLПаспорт85. Только собственная строка и память.

Подготовка

  1. Будущий ручной опыт выполняйте в своей новой пустой учебной конфигурации на платформе 8.5.1.1343, в толстом управляемом клиенте. Здесь создаётся только собственное дерево из фиксированной строки в памяти; файлы, Интернет и объекты рабочей базы не используются.

  2. Общие → Общие модули → создать HTMLПаспорт85. Сервер=Да; Глобальный=Нет; Привилегированный=Нет; Вызов сервера=Нет; оба клиентских флага=Нет; Внешнее соединение=Нет; повторное использование возвращаемых значений — Не использовать. Основной блок вставьте целиком в пустой модуль.

  3. Общие → Общие формы → создать управляемую форму HTMLПаспорт85. Добавьте реквизит Результат85: Строка неограниченной длины; выведите многострочным полем только для чтения. Создайте команду Проверить85, Действие=Проверить85, выведите её кнопку.

  4. У формы задайте АвтоматическоеСохранениеДанныхВНастройках=АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать и СохранениеДанныхВНастройках=СохранениеДанныхФормыВНастройках.НеИспользовать. Это два различных перечисления, не Булево. Не создавайте обработчики сохранения.

  5. Второй блок — целый модуль формы HTMLПаспорт85. Третий — целый модуль общей команды ОткрытьHTMLПаспорт85 без параметра. Общую команду включите в командный интерфейс собственной учебной подсистемы. Штатные параметры обоих обработчиков передаёт платформа; вручную их не вызывайте.

  6. Обновите конфигурацию собственной учебной базы, откройте форму общей командой и нажмите Проверить85. Разбор и изменения своих узлов выполняются на сервере; клиент получает только строку проверенного результата.

  7. Специальные HTML-классы старого DOM и часть операций не рекомендуются начиная с 8.2. Это узкий урок сопровождения старого кода, не способ управлять браузером и не рекомендация для нового веб-интерфейса.

  8. Этот код в 1С ещё не компилировался и не выполнялся. Неверный фактический тип, форма дерева, отказ операции или исключение означают остановку; сообщение об остановке не является успешным примером.

Функция ПрочитатьСвоюСтроку85(СтрокаHTML85)
    Чтение = Новый ЧтениеHTML;
    Если ТипЗнч(Чтение) <> Тип("ЧтениеHTML") Тогда
        ВызватьИсключение "Не создано настоящее ЧтениеHTML";
    КонецЕсли;
    Попытка
        Чтение.УстановитьСтроку(СтрокаHTML85);
        Построитель = Новый ПостроительDOM;
        Если ТипЗнч(Построитель) <> Тип("ПостроительDOM") Тогда
            ВызватьИсключение "Не создан настоящий ПостроительDOM";
        КонецЕсли;
        Документ = Построитель.Прочитать(Чтение);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Документ) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Не получен настоящий ДокументHTML";
    КонецЕсли;
    Возврат Документ;
КонецФункции

Функция НайтиСвойБлок85(Документ, Идентификатор85)
    Блок85 = Документ.ПолучитьЭлементПоИдентификатору(Идентификатор85);
    Если Блок85 = Неопределено Тогда
        ВызватьИсключение "В своей строке не найден нужный div";
    КонецЕсли;
    Если ТипЗнч(Блок85) <> Тип("ЭлементБлокHTML")
        Или Блок85.ДокументВладелец <> Документ Тогда
        ВызватьИсключение "Нужен настоящий собственный ЭлементБлокHTML";
    КонецЕсли;
    Возврат Блок85;
КонецФункции

Функция Проверить85() Экспорт
    Документ = ПрочитатьСвоюСтроку85("<html><head><title>Свои три узла</title></head><body><div id='triplet85' data-guide='A-01'>A-01<!--A-01--></div></body></html>");
    Блок85 = НайтиСвойБлок85(Документ, "triplet85");
    Атрибут85 = Блок85.ПолучитьУзелАтрибута("data-guide");
    Если ТипЗнч(Атрибут85) <> Тип("АтрибутHTML")
        Или ТипЗнч(Атрибут85.Значение) <> Тип("Строка") Или Атрибут85.Значение <> "A-01" Тогда
        ВызватьИсключение "Не получен настоящий собственный атрибут";
    КонецЕсли;
    Владелец85 = Атрибут85.ЭлементВладелец;
    Если ТипЗнч(Владелец85) <> Тип("ЭлементБлокHTML") Или Владелец85 <> Блок85 Тогда
        ВызватьИсключение "Не подтверждён фактический владелец своего атрибута";
    КонецЕсли;
    Узлы85 = Блок85.ДочерниеУзлы;
    Если ТипЗнч(Узлы85) <> Тип("СписокУзловHTML") Или Узлы85.Количество() <> 2 Тогда
        ВызватьИсключение "Нужны собственные текст и комментарий, а не атрибут в списке детей";
    КонецЕсли;
    Текст85 = Узлы85.Элемент(0);
    Пометка85 = Узлы85.Элемент(1);
    Если ТипЗнч(Текст85) <> Тип("ТекстHTML")
        Или ТипЗнч(Пометка85) <> Тип("КомментарийHTML")
        Или Текст85.ЗначениеУзла <> "A-01" Или Пометка85.Данные <> "A-01"
        Или Блок85.ТекстовоеСодержимое <> "A-01" Тогда
        ВызватьИсключение "Не получена собственная типизированная тройка A-01";
    КонецЕсли;
    Отчет185 = ПроверитьКопию85(Атрибут85, Документ, 1);
    Отчет285 = ПроверитьКопию85(Текст85, Документ, 2);
    Отчет385 = ПроверитьКопию85(Пометка85, Документ, 3);
    Отметка185 = Атрибут85.ПолучитьПользовательскиеДанные("own-html85-passport");
    Отметка285 = Текст85.ПолучитьПользовательскиеДанные("own-html85-passport");
    Отметка385 = Пометка85.ПолучитьПользовательскиеДанные("own-html85-passport");
    Если ТипЗнч(Отметка185) <> Тип("Число") Или Отметка185 <> 1
        Или ТипЗнч(Отметка285) <> Тип("Число") Или Отметка285 <> 2
        Или ТипЗнч(Отметка385) <> Тип("Число") Или Отметка385 <> 3 Тогда
        ВызватьИсключение "Не прочитаны реальные три отметки обработки";
    КонецЕсли;
    Итого85 = Отметка185 + Отметка285 + Отметка385;
    Если Итого85 <> 6 Или Атрибут85.Значение <> "A-01"
        Или Текст85.ЗначениеУзла <> "A-01" Или Пометка85.Данные <> "A-01"
        Или Блок85.ТекстовоеСодержимое <> "A-01"
        Или Блок85.ДочерниеУзлы.Количество() <> 2 Тогда
        ВызватьИсключение "Копии изменили собственные оригиналы или итог отметок";
    КонецЕсли;
    Возврат Отчет185 + Символы.ПС + Отчет285 + Символы.ПС + Отчет385 + Символы.ПС
        + "Оригиналы A-01 сохранены; копии B-02 проверены; сумма отметок: " + Строка(Итого85);
КонецФункции

Функция ПроверитьКопию85(Узел85, Документ, Номер85)
    Если ТипЗнч(Узел85) <> Тип("АтрибутHTML")
        И ТипЗнч(Узел85) <> Тип("ТекстHTML")
        И ТипЗнч(Узел85) <> Тип("КомментарийHTML") Тогда
        ВызватьИсключение "Нужен один из трёх настоящих собственных видов узла";
    КонецЕсли;
    Имя85 = Узел85.ИмяУзла;
    ТипУзла85 = Узел85.ТипУзла;
    Значение85 = Узел85.ЗначениеУзла;
    Содержимое85 = Узел85.ТекстовоеСодержимое;
    ЛокальноеИмя85 = Узел85.ЛокальноеИмя;
    Префикс85 = Узел85.Префикс;
    Дети85 = Узел85.ДочерниеУзлы;
    ЧислоДетей85 = Дети85.Количество();
    ЕстьДети85 = Узел85.ЕстьДочерниеУзлы();
    ЕстьАтрибуты85 = Узел85.ЕстьАтрибуты();
    Если ТипЗнч(Имя85) <> Тип("Строка") Или ТипЗнч(Значение85) <> Тип("Строка")
        Или Значение85 <> "A-01" Или ТипЗнч(Содержимое85) <> Тип("Строка")
        Или ТипЗнч(Дети85) <> Тип("СписокУзловHTML")
        Или ТипЗнч(ЧислоДетей85) <> Тип("Число")
        Или ТипЗнч(ЕстьДети85) <> Тип("Булево") Или ЕстьДети85 <> (ЧислоДетей85 > 0)
        Или ТипЗнч(ЕстьАтрибуты85) <> Тип("Булево") Или ЕстьАтрибуты85
        Или Узел85.Атрибуты <> Неопределено Или Узел85.ДокументВладелец <> Документ Тогда
        ВызватьИсключение "Исходный фактический паспорт не соответствует своему узлу";
    КонецЕсли;
    Если ТипЗнч(Узел85) = Тип("АтрибутHTML") Тогда
        Если ЧислоДетей85 < 0 Или ЧислоДетей85 > 1 Тогда
            ВызватьИсключение "Не поддержана фактическая форма значения атрибута";
        КонецЕсли;
        Если ЧислоДетей85 = 1 Тогда
            Ребенок85 = Дети85.Элемент(0);
            Если ТипЗнч(Ребенок85) <> Тип("ТекстHTML") Или Ребенок85.ЗначениеУзла <> "A-01" Тогда
                ВызватьИсключение "Не прочитан настоящий текстовый ребёнок атрибута";
            КонецЕсли;
        КонецЕсли;
    Иначе
        Если ЧислоДетей85 <> 0 Или Префикс85 <> Неопределено Тогда
            ВызватьИсключение "Текст и комментарий должны быть листовыми узлами без префикса";
        КонецЕсли;
    КонецЕсли;
    СтарыеДанные85 = Узел85.УстановитьПользовательскиеДанные("own-html85-passport", Номер85);
    Если СтарыеДанные85 <> Неопределено
        Или Узел85.ПолучитьПользовательскиеДанные("own-html85-passport") <> Номер85 Тогда
        ВызватьИсключение "Собственная новая отметка не установлена";
    КонецЕсли;
    Копия85 = Узел85.КлонироватьУзел(Истина);
    Если ТипЗнч(Копия85) <> ТипЗнч(Узел85) Тогда
        ВызватьИсключение "Копия не имеет фактический исходный тип HTML";
    КонецЕсли;
    РавенДо85 = Узел85.УзелРавен(Копия85);
    Идентичен85 = Узел85.УзелИдентичен(Копия85);
    Если ТипЗнч(РавенДо85) <> Тип("Булево") Или Не РавенДо85
        Или ТипЗнч(Идентичен85) <> Тип("Булево") Или Идентичен85
        Или Копия85.РодительскийУзел <> Неопределено
        Или Копия85.ПредыдущийСоседний <> Неопределено
        Или Копия85.СледующийСоседний <> Неопределено
        Или Копия85.ПолучитьПользовательскиеДанные("own-html85-passport") <> Неопределено Тогда
        ВызватьИсключение "Не подтверждена настоящая отдельная копия без отметок";
    КонецЕсли;
    Если Копия85.ИмяУзла <> Имя85 Или Копия85.ТипУзла <> ТипУзла85
        Или Копия85.ЗначениеУзла <> Значение85 Или Копия85.ТекстовоеСодержимое <> Содержимое85
        Или Копия85.ЛокальноеИмя <> ЛокальноеИмя85 Или Копия85.Префикс <> Префикс85
        Или Копия85.Атрибуты <> Неопределено Или Копия85.ДокументВладелец <> Документ
        Или Копия85.ДочерниеУзлы.Количество() <> ЧислоДетей85
        Или Копия85.ЕстьДочерниеУзлы() <> ЕстьДети85 Или Копия85.ЕстьАтрибуты() <> ЕстьАтрибуты85 Тогда
        ВызватьИсключение "Повторное чтение копии не совпало с фактическим паспортом";
    КонецЕсли;
    Дополнение85 = "";
    Если ТипЗнч(Копия85) = Тип("АтрибутHTML") Тогда
        АтрибутКопия85 = Копия85;
        АтрибутКопия85.Значение = "B-02";
        НовыеДети85 = АтрибутКопия85.ДочерниеУзлы;
        Если ТипЗнч(НовыеДети85) <> Тип("СписокУзловHTML") Или НовыеДети85.Количество() <> 1 Тогда
            ВызватьИсключение "Запись значения копии не создала один настоящий текстовый узел";
        КонецЕсли;
        НовыйТекст85 = НовыеДети85.Элемент(0);
        Если ТипЗнч(НовыйТекст85) <> Тип("ТекстHTML") Или НовыйТекст85.ЗначениеУзла <> "B-02"
            Или АтрибутКопия85.Значение <> "B-02" Тогда
            ВызватьИсключение "Не подтверждено новое значение только копии атрибута";
        КонецЕсли;
        Дополнение85 = "Детей атрибута до: " + Строка(ЧислоДетей85)
            + "; после изменения копии: " + Строка(НовыеДети85.Количество());
    Иначе
        ЛистоваяКопия85 = Копия85;
        Если ЛистоваяКопия85.ДочерниеУзлы.Количество() <> 0
            Или ЛистоваяКопия85.ПервыйДочерний <> Неопределено
            Или ЛистоваяКопия85.ПоследнийДочерний <> Неопределено Тогда
            ВызватьИсключение "Листовая копия неожиданно имеет детей";
        КонецЕсли;
        ЛистоваяКопия85.ЗначениеУзла = "B-02";
        Пробелы85 = ЛистоваяКопия85.ЭтоПробельныеСимволыЭлемента;
        Если ТипЗнч(Пробелы85) <> Тип("Булево") Тогда
            ВызватьИсключение "Не получен фактический признак пробельного текста";
        КонецЕсли;
        Дополнение85 = "Признак пробелов: " + Строка(Пробелы85);
        Если ТипЗнч(ЛистоваяКопия85) = Тип("КомментарийHTML") Тогда
            КопияПометки85 = ЛистоваяКопия85;
            ПолныйПометки85 = КопияПометки85.ПолныйТекст;
            Если ТипЗнч(ПолныйПометки85) <> Тип("Строка") Тогда
                ВызватьИсключение "Не прочитан фактический полный текст копии комментария";
            КонецЕсли;
            Дополнение85 = Дополнение85 + "; фактический полный текст: " + ПолныйПометки85;
        КонецЕсли;
    КонецЕсли;
    РавенПосле85 = Узел85.УзелРавен(Копия85);
    Если ТипЗнч(РавенПосле85) <> Тип("Булево") Или РавенПосле85
        Или Копия85.ЗначениеУзла <> "B-02" Или Узел85.ЗначениеУзла <> Значение85
        Или Узел85.ИмяУзла <> Имя85 Или Узел85.ТипУзла <> ТипУзла85
        Или Узел85.ТекстовоеСодержимое <> Содержимое85
        Или Узел85.ЛокальноеИмя <> ЛокальноеИмя85 Или Узел85.Префикс <> Префикс85
        Или Узел85.ДочерниеУзлы.Количество() <> ЧислоДетей85
        Или Узел85.ПолучитьПользовательскиеДанные("own-html85-passport") <> Номер85 Тогда
        ВызватьИсключение "Независимость изменённой копии от оригинала не подтверждена";
    КонецЕсли;
    Возврат "Узел " + Строка(Номер85) + ": имя=" + Имя85 + "; тип=" + Строка(ТипУзла85)
        + "; оригинал=" + Узел85.ЗначениеУзла + "; копия=" + Копия85.ЗначениеУзла
        + "; локальное имя=" + Строка(ЛокальноеИмя85) + "; префикс=" + Строка(Префикс85)
        + "; текст до=" + Содержимое85 + "; отметка=" + Строка(Узел85.ПолучитьПользовательскиеДанные("own-html85-passport"))
        + "; " + Дополнение85;
КонецФункции
Целый модуль своей управляемой формы HTMLПаспорт85

Общие → Общие формы → HTMLПаспорт85 → пустой модуль. Вставить целиком; Результат85 — строка; Действие команды Проверить85 связано с обработчиком.

Клиент — настоящий обработчик команды; сервер — ПолучитьПротокол85НаСервере. По границе передаётся только строка.

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

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

Общие → Общие команды → ОткрытьHTMLПаспорт85 → пустой модуль. Без параметра; включить в собственный командный интерфейс.

Толстый управляемый клиент, &НаКлиенте. Настоящий ОбработкаКоманды с двумя штатными параметрами.

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

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

  1. Своя строка содержит атрибут data-guide, видимый текст и комментарий со значением A-01. Атрибут получается через ПолучитьУзелАтрибута, а два ребёнка — из настоящего ограниченного списка; каждый специальный тип проверяется до его свойств.

  2. Паспорт читает реальные имена, тип узла, значения, текст, локальное имя, префикс, число детей и признаки атрибутов. Эти данные сравниваются с копией и выводятся, а не подменяются именами #text/#comment или выдуманными пустыми пространствами имён.

  3. Три настоящие отметки 1, 2 и 3 устанавливаются на исходных узлах. КлонироватьУзел(Истина) возвращает общий набор HTML-типов: у каждой фактической копии проверяется исходный тип, равенство содержания и отсутствие идентичности.

  4. Копии не вставляются в дерево. Их фактические родитель, предыдущий и следующий сосед должны быть Неопределено; пользовательская отметка не копируется. Так изучаются отдельные копии, а не спорные соседние объекты разных классов.

  5. Меняется только копия: Значение атрибута либо ЗначениеУзла текста/комментария становится B-02. У атрибута настоящий setter создаёт текстового ребёнка, который заново читается через широкий СписокУзловHTML и проверяется как ТекстHTML.

  6. ПервыйДочерний и ПоследнийДочерний используются только у фактических листовых копий текста/комментария. У атрибута эти два свойства не демонстрируются: их объявленный тип АтрибутHTML не подтверждает текстового ребёнка.

  7. После изменения родные узлы повторно читаются как A-01; копия уже не равна оригиналу, но это не повреждает исходную страницу. Отдельно читаются реальные три числовые отметки и вычисляется их сумма 6.

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

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

  1. Первый будущий запуск: три строки паспорта показывают реальные имена/типы; оригиналы остаются A-01, отдельные копии прочитаны как B-02, фактическая сумма отметок равна 6.

  2. Проследите настоящие три типа до КлонироватьУзел, затем отдельный фактический тип каждой копии. До изменения равенство Истина, идентичность Ложь; после изменения равенство Ложь.

  3. В отладчике у настоящих отделённых копий проверьте фактические Неопределено у родителя и соседей и отсутствие скопированных пользовательских отметок. Не прикрепляйте копии для искусственного исправления проверки.

  4. У исходного атрибута допускается только измеренная форма 0/1 ребёнок. После записи значения копии должен быть один настоящий текстовый ребёнок B-02; исходный атрибут и страница не меняются.

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

  6. При неподдержанной фактической форме дерева или исключении нет успешного протокола. Состояние предыдущего отчёта очищается; ошибочный вызов не повторяется автоматически.

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

При полном успешном контроле: три реальные отдельные копии B-02, неизменные оригиналы A-01 и сумма трёх реально прочитанных отметок 6. Конкретные имена/полный текст устаревших свойств показываются как наблюдения.

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

  1. Модель создаётся только из собственной фиксированной строки. Нельзя подставлять внешний документ, объект пользователя, файл, URL или рабочие данные и считать этот пример проверкой их безопасности.

  2. Установленная 8.5.1.1343 объявляет СоздатьКомментарий → КомментарийDOM и СоздатьТекстовыйУзел → ТекстDOM. Они не служат доказательством специальных HTML-получателей. Здесь реальные специальные узлы происходят из собственного HTMLReader/DOMBuilder и проверяются.

  3. Общий возвращаемый HTML-тип не обещает конкретный класс в любой среде. Несовпадение фактического типа/формы означает остановку и неподтверждённый опыт, не успешный обход ошибки.

  4. Не переносите правила имён, соседей и пространств имён из W3C по памяти. Сохраняются точные объявленные локальные контракты и реальные наблюдения; данные узлов не приводятся к другому классу.

  5. Чтение закрывается на нормальном пути и в обработчике ошибки; исключение повторно вызывается. Ошибка самого закрытия тоже останавливает опыт: успешная очистка при любом отказе не обещается.

  6. Нативные тексты справки и существующие конфигурационные образцы не исправлялись. Компилятор и 1С во время подготовки не запускались; статические проверки не являются выполнением примера.

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

Граница нормализации HTML: лист сохраняет соседей, родитель объединяет тексты

На настоящих листовых ТекстHTML и КомментарийHTML своей строки проверить неизменность полного дерева после их Normalize. Затем показать контраст с уже покрытым DIV.Normalize: реальные соседние A-/01 превращаются в один A-01, а пометка и вычисленный счёт 750 сохраняются.

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

Сервер: собственный неглобальный непривилегированный HTMLГраница85; parser и все HTML/DOM объекты серверные. Клиент получает только строковый отчёт.

Подготовка

  1. Будущий ручной опыт: собственная НОВАЯ пустая учебная конфигурация на Windows, платформа 8.5.1.1343, управляемое приложение и толстый управляемый клиент. Не рабочая УТ, КА, УНФ или БП. HTML, reader, контрольная копия и расчёт создаются только в памяти одной функции без параметров; чужих объектов, файлов, URL и браузера нет.

  2. Общие → Общие модули → создать HTMLГраница85. Сервер=Да; Глобальный, Привилегированный, Вызов сервера, Клиент (управляемое приложение), Клиент (обычное приложение), Внешнее соединение=Нет. Повторное использование возвращаемых значений=Не использовать. Основной блок вставьте ЦЕЛИКОМ в пустой модуль; единственная экспортная функция Проверить85 не принимает входных объектов.

  3. Общие → Общие формы → создать управляемую ГраницаНормализацииHTML85. Один реквизит Результат85: Строка неограниченной длины. Выведите многострочное поле с ПутьКДанным=Результат85, ТолькоПросмотр=Да. Других данных, HTML-поля и событий автоматического запуска не требуется.

  4. В свойствах своей формы: АвтоматическоеСохранениеДанныхВНастройках=АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать; СохранениеДанныхВНастройках=СохранениеДанныхФормыВНастройках.НеИспользовать. Это два разных перечисления, не Булево.

  5. Создайте в форме команду Проверить85: Действие=Проверить85. Создайте кнопку и свяжите с этой командой. Поддерживающий модуль формы вставьте ЦЕЛИКОМ. Настоящий объект Команда передаёт платформа при нажатии; обработчик не вызывайте вручную.

  6. Общие → Общие команды → создать ОткрытьГраницуHTML85 без параметра, включить в командный интерфейс своей учебной подсистемы. Третий блок вставить ЦЕЛИКОМ в пустой модуль этой общей команды; &НаКлиенте задаёт настоящий контекст, а #Если проверяет вид клиентского приложения.

  7. После будущей проверки синтаксиса сохраните свою конфигурацию и обновите только её учебную базу. Откройте толстый управляемый клиент, своей общей командой откройте форму и нажмите Проверить85. Сервер возвращает только строку, не DOM-объекты. Этот запуск в 1С здесь не выполнялся.

  8. Для этой модели памяти не нужны отдельная VM, новый системный пользователь, UUID каталога или полный анализ метаданных. Новое нажатие создаёт новый собственный документ; ошибки предыдущего запуска не чинятся и не продолжаются, старая строка очищается перед обращением к серверу.

Функция ПрочитатьHTML85()
    HTML85 = "<html><head><title>Граница нормализации</title></head><body><div id='left85'>A-</div><div id='right85'>01</div><div id='code85'></div><div id='note85'><!--ORDER:A-01--></div><div id='quantity85'>3</div><div id='price85'>250</div><div id='control85'>НЕ МЕНЯТЬ</div></body></html>";
    Читатель85 = Новый ЧтениеHTML;
    Попытка
        Читатель85.УстановитьСтроку(HTML85);
        Построитель85 = Новый ПостроительDOM;
        Документ85 = Построитель85.Прочитать(Читатель85);
    Исключение
        Читатель85.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Читатель85.Закрыть();
    Если ТипЗнч(Документ85) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Собственная строка не дала настоящий ДокументHTML";
    КонецЕсли;
    Возврат Документ85;
КонецФункции

Функция ПолучитьБлок85(Документ85, Идентификатор85)
    Блок85 = Документ85.ПолучитьЭлементПоИдентификатору(Идентификатор85);
    Если ТипЗнч(Блок85) <> Тип("ЭлементБлокHTML") Или Блок85.ДокументВладелец <> Документ85 Тогда
        ВызватьИсключение "Не найден нужный собственный DIV этого документа";
    КонецЕсли;
    Возврат Блок85;
КонецФункции

Процедура ПроверитьТекст85(Текст85, Документ85, Данные85)
    Если ТипЗнч(Текст85) <> Тип("ТекстHTML") Или Текст85.ДокументВладелец <> Документ85
        Или ТипЗнч(Текст85.Данные) <> Тип("Строка") Или Текст85.Данные <> Данные85
        Или Текст85.ДочерниеУзлы.Количество() <> 0 Или Текст85.Атрибуты <> Неопределено Тогда
        ВызватьИсключение "Нужен настоящий собственный текстовый лист с точными данными";
    КонецЕсли;
КонецПроцедуры

Функция ПрочитатьОдинТекст85(Документ85, Идентификатор85, Данные85)
    Список85 = ПолучитьБлок85(Документ85, Идентификатор85).ДочерниеУзлы;
    Количество85 = Список85.Количество();
    Если ТипЗнч(Список85) <> Тип("СписокУзловHTML") Или ТипЗнч(Количество85) <> Тип("Число") Или Количество85 <> 1 Тогда
        ВызватьИсключение "В своём блоке ожидается ровно один реальный текст";
    КонецЕсли;
    Текст85 = Список85.Элемент(0);
    ПроверитьТекст85(Текст85, Документ85, Данные85);
    Возврат Текст85;
КонецФункции

Функция ПроверитьДваТекста85(Документ85, Левый85, Правый85, ДанныеЛевого85, ДанныеПравого85)
    Если ПолучитьБлок85(Документ85, "left85").ДочерниеУзлы.Количество() <> 0
        Или ПолучитьБлок85(Документ85, "right85").ДочерниеУзлы.Количество() <> 0 Тогда
        ВызватьИсключение "Оба исходных текста должны быть перенесены из своих прежних блоков";
    КонецЕсли;
    Список85 = ПолучитьБлок85(Документ85, "code85").ДочерниеУзлы;
    Количество85 = Список85.Количество();
    Если ТипЗнч(Список85) <> Тип("СписокУзловHTML") Или ТипЗнч(Количество85) <> Тип("Число") Или Количество85 <> 2 Тогда
        ВызватьИсключение "У собственного родителя должны остаться два текста, а не один";
    КонецЕсли;
    Первый85 = Список85.Элемент(0);
    Второй85 = Список85.Элемент(1);
    ПроверитьТекст85(Первый85, Документ85, ДанныеЛевого85);
    ПроверитьТекст85(Второй85, Документ85, ДанныеПравого85);
    ТотЖеПервый85 = Первый85.УзелИдентичен(Левый85);
    ТотЖеВторой85 = Второй85.УзелИдентичен(Правый85);
    Если ТипЗнч(ТотЖеПервый85) <> Тип("Булево") Или Не ТотЖеПервый85
        Или ТипЗнч(ТотЖеВторой85) <> Тип("Булево") Или Не ТотЖеВторой85 Тогда
        ВызватьИсключение "Порядок и настоящая идентичность обоих собственных листьев изменились";
    КонецЕсли;
    Блок85 = ПолучитьБлок85(Документ85, "code85");
    Если ТипЗнч(Блок85.ТекстовоеСодержимое) <> Тип("Строка")
        Или Блок85.ТекстовоеСодержимое <> ДанныеЛевого85 + ДанныеПравого85 Тогда
        ВызватьИсключение "Полное текстовое значение собственного родителя изменилось";
    КонецЕсли;
    Возврат Количество85;
КонецФункции

Функция ПроверитьПометку85(Документ85, Пометка85, ДанныеПометки85)
    Список85 = ПолучитьБлок85(Документ85, "note85").ДочерниеУзлы;
    Если ТипЗнч(Список85) <> Тип("СписокУзловHTML") Или Список85.Количество() <> 1 Тогда
        ВызватьИсключение "Ожидается одна собственная техническая пометка";
    КонецЕсли;
    ПрочитаннаяПометка85 = Список85.Элемент(0);
    Если ТипЗнч(ПрочитаннаяПометка85) <> Тип("КомментарийHTML")
        Или ПрочитаннаяПометка85.ДокументВладелец <> Документ85
        Или ТипЗнч(ПрочитаннаяПометка85.Данные) <> Тип("Строка")
        Или ПрочитаннаяПометка85.Данные <> ДанныеПометки85
        Или ПрочитаннаяПометка85.ДочерниеУзлы.Количество() <> 0
        Или ПрочитаннаяПометка85.Атрибуты <> Неопределено Тогда
        ВызватьИсключение "Собственная пометка перестала быть точным листовым комментарием";
    КонецЕсли;
    ТаЖеПометка85 = ПрочитаннаяПометка85.УзелИдентичен(Пометка85);
    Если ТипЗнч(ТаЖеПометка85) <> Тип("Булево") Или Не ТаЖеПометка85 Тогда
        ВызватьИсключение "Вместо прежней собственной пометки оказался другой узел";
    КонецЕсли;
    Возврат ПрочитаннаяПометка85.Данные;
КонецФункции

Функция ПрочитатьСчёт85(Документ85)
    ТекстКоличества85 = ПрочитатьОдинТекст85(Документ85, "quantity85", "3");
    ТекстЦены85 = ПрочитатьОдинТекст85(Документ85, "price85", "250");
    Контроль85 = ПрочитатьОдинТекст85(Документ85, "control85", "НЕ МЕНЯТЬ");
    Количество85 = Число(ТекстКоличества85.Данные);
    Цена85 = Число(ТекстЦены85.Данные);
    Сумма85 = Количество85 * Цена85;
    Если ТипЗнч(Количество85) <> Тип("Число") Или Количество85 <> 3
        Или ТипЗнч(Цена85) <> Тип("Число") Или Цена85 <> 250 Или Сумма85 <> 750 Тогда
        ВызватьИсключение "Реальные данные своего счёта не подтвердили 3 × 250 = 750";
    КонецЕсли;
    Возврат Строка(Количество85) + " × " + Строка(Цена85) + " = " + Строка(Сумма85) + "; " + Контроль85.Данные;
КонецФункции

Процедура ПроверитьРавенство85(Документ85, Копия85)
    Равен85 = Документ85.УзелРавен(Копия85);
    Если ТипЗнч(Равен85) <> Тип("Булево") Или Не Равен85 Тогда
        ВызватьИсключение "Изменилось полное логическое дерево, а не только разрешённая структура";
    КонецЕсли;
КонецПроцедуры

Функция Проверить85() Экспорт
    Документ85 = ПрочитатьHTML85();
    Левый85 = ПрочитатьОдинТекст85(Документ85, "left85", "A-");
    Правый85 = ПрочитатьОдинТекст85(Документ85, "right85", "01");
    ДанныеЛевого85 = Левый85.Данные;
    ДанныеПравого85 = Правый85.Данные;
    Код85 = ДанныеЛевого85 + ДанныеПравого85;
    СписокПометок85 = ПолучитьБлок85(Документ85, "note85").ДочерниеУзлы;
    Если ТипЗнч(СписокПометок85) <> Тип("СписокУзловHTML") Или СписокПометок85.Количество() <> 1 Тогда
        ВызватьИсключение "Своя пометка не подготовлена";
    КонецЕсли;
    Пометка85 = СписокПометок85.Элемент(0);
    Если ТипЗнч(Пометка85) <> Тип("КомментарийHTML") Тогда
        ВызватьИсключение "Нужен КомментарийHTML из собственной разобранной строки, не новый XML-комментарий";
    КонецЕсли;
    ПометкаДо85 = ПроверитьПометку85(Документ85, Пометка85, "ORDER:" + Код85);
    СчётДо85 = ПрочитатьСчёт85(Документ85);
    КодовыйБлок85 = ПолучитьБлок85(Документ85, "code85");
    Если КодовыйБлок85.ДочерниеУзлы.Количество() <> 0 Тогда
        ВызватьИсключение "Свой кодовый блок должен начинаться пустым";
    КонецЕсли;
    ДобавленЛевый85 = КодовыйБлок85.ДобавитьДочерний(Левый85);
    Если ТипЗнч(ДобавленЛевый85) <> Тип("ТекстHTML") Или Не ДобавленЛевый85.УзелИдентичен(Левый85)
        Или ПолучитьБлок85(Документ85, "left85").ДочерниеУзлы.Количество() <> 0
        Или КодовыйБлок85.ДочерниеУзлы.Количество() <> 1 Тогда
        ВызватьИсключение "Первый собственный текст не перенесён";
    КонецЕсли;
    ДобавленПравый85 = КодовыйБлок85.ДобавитьДочерний(Правый85);
    Если ТипЗнч(ДобавленПравый85) <> Тип("ТекстHTML") Или Не ДобавленПравый85.УзелИдентичен(Правый85) Тогда
        ВызватьИсключение "Второй собственный текст не перенесён";
    КонецЕсли;
    До85 = ПроверитьДваТекста85(Документ85, Левый85, Правый85, ДанныеЛевого85, ДанныеПравого85);
    Копия85 = Документ85.КлонироватьУзел(Истина);
    Если ТипЗнч(Копия85) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Для полного контроля нужна настоящая глубокая копия ДокументHTML";
    КонецЕсли;
    ТаЖеКопия85 = Копия85.УзелИдентичен(Документ85);
    Если ТипЗнч(ТаЖеКопия85) <> Тип("Булево") Или ТаЖеКопия85 Тогда
        ВызватьИсключение "Контрольная копия не должна ссылаться на рабочий документ";
    КонецЕсли;
    ПроверитьРавенство85(Документ85, Копия85);
    Если ПолучитьБлок85(Копия85, "code85").ДочерниеУзлы.Количество() <> 2 Тогда
        ВызватьИсключение "Глубокая копия должна сохранить именно два соседних текста";
    КонецЕсли;
    Левый85.Нормализовать();
    ПослеТекста85 = ПроверитьДваТекста85(Документ85, Левый85, Правый85, ДанныеЛевого85, ДанныеПравого85);
    Если ПроверитьПометку85(Документ85, Пометка85, ПометкаДо85) <> ПометкаДо85
        Или ПрочитатьСчёт85(Документ85) <> СчётДо85 Тогда
        ВызватьИсключение "Листовая нормализация текста изменила свою пометку или счёт";
    КонецЕсли;
    ПроверитьРавенство85(Документ85, Копия85);
    Пометка85.Нормализовать();
    ПослеПометки85 = ПроверитьДваТекста85(Документ85, Левый85, Правый85, ДанныеЛевого85, ДанныеПравого85);
    Если ПроверитьПометку85(Документ85, Пометка85, ПометкаДо85) <> ПометкаДо85
        Или ПрочитатьСчёт85(Документ85) <> СчётДо85 Тогда
        ВызватьИсключение "Листовая нормализация комментария изменила свои данные";
    КонецЕсли;
    ПроверитьРавенство85(Документ85, Копия85);
    КодовыйБлок85 = ПолучитьБлок85(Документ85, "code85");
    КодовыйБлок85.Нормализовать();
    КонечныйТекст85 = ПрочитатьОдинТекст85(Документ85, "code85", Код85);
    ПослеРодителя85 = КодовыйБлок85.ДочерниеУзлы.Количество();
    КодПосле85 = КодовыйБлок85.ТекстовоеСодержимое;
    Если ТипЗнч(КодПосле85) <> Тип("Строка") Или КодПосле85 <> КонечныйТекст85.Данные Тогда
        ВызватьИсключение "Перечитанный целый код не совпал с настоящим объединённым текстом";
    КонецЕсли;
    БлокКопии85 = ПолучитьБлок85(Копия85, "code85");
    Если БлокКопии85.ДочерниеУзлы.Количество() <> 2 Тогда
        ВызватьИсключение "Нетронутая контрольная копия неожиданно изменилась";
    КонецЕсли;
    БлокКопии85.Нормализовать();
    ТекстКопии85 = ПрочитатьОдинТекст85(Копия85, "code85", Код85);
    Если ТекстКопии85.Данные <> КонечныйТекст85.Данные Тогда
        ВызватьИсключение "В реальной и ожидаемой структуре не совпал код";
    КонецЕсли;
    ПроверитьРавенство85(Документ85, Копия85);
    ПометкаПосле85 = ПроверитьПометку85(Документ85, Пометка85, ПометкаДо85);
    СчётПосле85 = ПрочитатьСчёт85(Документ85);
    Если ТипЗнч(ПослеРодителя85) <> Тип("Число") Или ПослеРодителя85 <> 1
        Или ПометкаПосле85 <> ПометкаДо85 Или СчётПосле85 <> СчётДо85
        Или ПолучитьБлок85(Документ85, "left85").ДочерниеУзлы.Количество() <> 0
        Или ПолучитьБлок85(Документ85, "right85").ДочерниеУзлы.Количество() <> 0 Тогда
        ВызватьИсключение "Полный итоговый контроль собственного документа не пройден";
    КонецЕсли;
    Возврат "Текстовых узлов: " + Строка(До85) + " → " + Строка(ПослеТекста85)
        + " → " + Строка(ПослеПометки85) + " → " + Строка(ПослеРодителя85)
        + ". Код: " + КодПосле85 + ". Пометка: " + ПометкаПосле85 + ". Счёт: " + СчётПосле85;
КонецФункции
Полный модуль собственной формы ГраницаНормализацииHTML85

Общие → Общие формы → ГраницаНормализацииHTML85 → пустой модуль формы. Вставить ЦЕЛИКОМ; своя команда Проверить85 связана через Действие.

Реальная команда формы &НаКлиенте; обращение к своему общему модулю &НаСервере. Передаётся только Строка.

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

&НаСервере
Функция ПроверитьНаСервере85()
    Если ИмяФормы <> "ОбщаяФорма.ГраницаНормализацииHTML85"
        Или АвтоматическоеСохранениеДанныхВНастройках <> АвтоматическоеСохранениеДанныхФормыВНастройках.НеИспользовать
        Или СохранениеДанныхВНастройках <> СохранениеДанныхФормыВНастройках.НеИспользовать Тогда
        ВызватьИсключение "Нужна своя форма с отключённым сохранением данных";
    КонецЕсли;
    Отчёт85 = HTMLГраница85.Проверить85();
    Если ТипЗнч(Отчёт85) <> Тип("Строка") Или Отчёт85 = "" Тогда
        ВызватьИсключение "Не получен полный строковый результат своего серверного модуля";
    КонецЕсли;
    Возврат Отчёт85;
КонецФункции
Полный модуль собственной общей команды ОткрытьГраницуHTML85

Общие → Общие команды → ОткрытьГраницуHTML85 → пустой модуль команды. Вставить ЦЕЛИКОМ, включить без параметра в свой учебный интерфейс.

&НаКлиенте; толстый управляемый клиент, настоящее ОбработкаКоманды с двумя штатными параметрами.

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

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

  1. Разбор строки — настоящий producer: ЧтениеHTML.УстановитьСтроку и ПостроительDOM.Прочитать. Для HTML reader native обещает ДокументHTML. ПолучитьЭлементПоИдентификатору обещает лишь общий ЭлементHTML либо Неопределено, поэтому каждый нужный DIV принимается только после фактического ЭлементБлокHTML и правильного документа-владельца.

  2. СписокУзловHTML.Элемент читается только после проверки количества. Так получаются настоящие ТекстHTML A-/01 и КомментарийHTML ORDER:A-01. Прямых конструкторов листьев и CreateTextNode/CreateComment нет: их DOM returns нельзя называть HTML returns.

  3. Два текста реально переносятся из собственных left/right в пустой code через ДобавитьДочерний у DIV. Возвращённые узлы, прежние пустые места, порядок и идентичность проверяются. Значения A-/01 не присваиваются новым фальшивым листьям.

  4. Глубокая отдельная копия всего подготовленного дерева должна сохранить два соседних текста и быть native равна рабочему документу, но не идентична ему. До двух листовых вызовов контрольная копия не нормализуется и не изменяется.

  5. Первый вызов — Левый85.Нормализовать() на реальном текстовом листе без детей и атрибутов. Его поддерево не включает родителя и соседний текст. После вызова заново читаются два прежних узла, их реальные данные/идентичность/владельцы, пометка и счёт; весь документ сравнивается с нетронутой глубокой копией.

  6. Второй вызов — Пометка85.Нормализовать() на настоящем листовом комментарии. Его данные и само место в note сохраняются; родитель code всё ещё содержит два текста. Полное повторное чтение и native равенство всего документа проверяются снова. Это полезный наблюдаемый no-op, не слияние детей комментария.

  7. Только теперь контраст: Нормализовать() у собственного code DIV. Fresh список содержит один настоящий ТекстHTML со всем A-01. Старые ссылки на два листа после слияния больше не разыменовываются: справка не обещает, какой из них останется.

  8. Нетронутая контрольная копия всё ещё имеет два текста. Только её собственный code DIV затем нормализуется до ожидаемого одного A-01. Native равенство всего рабочего документа с такой отдельной ожидаемой копией подтверждает, что остальная логическая структура не изменилась. Это не ремонт живого документа и не откат после ошибки.

  9. Реальные строки количества3/цены250 преобразуются в числа, их произведение750 проверяется и перечитывается на границах. Итоговый отчёт использует настоящие количества2/2/2/1, прочитанный A-01, сохранённую пометку и расчёт, не заранее записанные числа успеха.

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

  1. Будущий успешный опыт: текстовых узлов 2 → 2 после текстового листа → 2 после комментария → 1 после родителя. Код A-01, пометка ORDER:A-01, счёт 3 × 250 = 750 и контрольный текст НЕ МЕНЯТЬ сохраняются.

  2. В собственном учебном отладчике до и после двух листовых вызовов посмотрите реальные child counts0 и Атрибуты=Неопределено у листьев. В code должны оставаться оба прежних ТекстHTML с A-/01; native равенство всего документа с нетронутой отдельной копией должно быть Булево Истина.

  3. После вызова у родителя заново получите единственный ребёнок через список. Требуется actual ТекстHTML с Data A-01, а не назначенный заранее результат. Не проверяйте сохранение старой ссылки на второй лист.

  4. В отдельной собственной подготовке измените строку цены, пометку или контрольный текст. Ожидается прекращение проверки, а не подстановка750/старого успеха. Эти отрицательные случаи ещё не выполнялись в 1С; не объявляйте их измеренным результатом.

  5. При исключении форма показывает «Опыт НЕ завершён» и повторно вызывает ошибку. Для нового ручного опыта нажмите кнопку заново только после разбора причины: создастся новое дерево, не продолжение частичного старого состояния.

  6. Проверьте точные места вставки всех трёх полных модулей и два enum сохранения формы. Тонкий/веб-клиент не используется для producer: метод ПостроительDOM.Прочитать и Data legacy листьев имеют собственную ограниченную доступность.

  7. СравнитьПозициюВДокументе не вызывается: три native страницы не определяют возвращаемый контракт. W3C числа/маски здесь не подставляются; новые PRIMARY ровно два листовых Normalize.

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

Ожидаемый будущий ручной результат: реальные code числа детей 2 → 2 → 2 → 1, перечитанный код A-01, пометка ORDER:A-01, счёт3 × 250 = 750 и НЕ МЕНЯТЬ. Два листовых вызова являются наблюдаемым no-op на своём поддереве; слияние происходит только у родителя. Запуск в 1С пока не выполнен.

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

  1. ТекстHTML и КомментарийHTML не рекомендуется использовать начиная с 8.2. Это ограниченный урок поддержки старого механизма 8.5.1.1343, а не новый браузерный интерфейс. Реальная parse shape и положительный путь ещё требуют ручного запуска; неподходящий тип/состав означает незавершённый опыт.

  2. Нормализовать имеет нулевую арность и применяется как statement: результат не присваивается. Сфера действия — поддерево данного receiver, включая его атрибуты; соседние узлы родителя туда не входят. Отсутствие изменения у подтверждённого листа не выдаётся за слияние или ошибку.

  3. Readonly ДочерниеУзлы/ДокументВладелец/Атрибуты не устанавливаются. Data и TextContent также нигде не присваиваются: родительское2→1 должно возникнуть именно через native Normalize. Attributes формально подписано коллекцией, но его native таблица явно задаёт Неопределено для Text/Comment; конкретный leaf count0 проверяется, не обещается для любого объекта.

  4. УзелРавен сравнивает логическую структуру, типы, значения, атрибуты и порядок/длину детей; не доказывает совпадение владельцев, родительских ссылок, пользовательских данных, сериализованных байтов или внешнего вида. Собственный owner и retained identities проверяются отдельно.

  5. Контрольная копия специально не нормализована до двух leaf-checks: иначе исчезнут два подготовленных соседних текста. Рекомендация нормализовать перед обычным сравнением здесь не используется, потому что предмет опыта — именно структура. Копия нормализуется отдельно только после обоих листовых опытов и настоящего родительского слияния.

  6. Reader.Close находится в обеих ветках, а SetString тоже внутри Попытка. Если Close сам выбросит исключение в ветке ошибки, он может скрыть первоначальную ошибку. Код честно останавливается; не обещает сохранение первоначальной причины, успешное закрытие или автоматическое восстановление.

  7. Никаких файлов, сети, HTML-рендеринга, запросов/записей БД, пользовательских профилей, печати и живого ремонта дерева. Статические проверки исходника/native contracts не являются компиляцией или выполнением1С.

  8. Формат Строка(Число) зависит от национальных установок; важны реальные числа и структура, а не побайтное совпадение текста отчёта. Имена/команды формы — учебные маршруты, не защита от подделки вызова.

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

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

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

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

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