ТекстHTML.Нормализовать

Методы · Normalize

Приводит все узлы Текст на полной глубине поддерева данного узла, включая узлы Атрибут, в "нормальную" форму, где только структуры (например, элементы, комментарии) разделяются текстовыми узлами, т.е. смежные текстовые узлы отсутствуют.

Синтаксис

Нормализовать()
Полное описание, параметры и ограничения

ТекстHTML.Нормализовать (HTMLText.Normalize)

ТекстHTML (HTMLText)

Нормализовать (Normalize)

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

Синтаксис:
Нормализовать()
Описание:

Приводит все узлы Текст на полной глубине поддерева данного узла, включая узлы Атрибут, в "нормальную" форму, где только структуры (например, элементы, комментарии) разделяются текстовыми узлами, т.е. смежные текстовые узлы отсутствуют.

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

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

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

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

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

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

Граница нормализации 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С» и не аффилирован с ней.