ДокументHTML.Нормализовать

Методы · Normalize

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

Синтаксис

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

ДокументHTML.Нормализовать (HTMLDocument.Normalize)

ДокументHTML (HTMLDocument)

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

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

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

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

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

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

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

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

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

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

Нормализовать соседние текстовые узлы собственного HTML-документа

У собственного блока создаём два соседних текста Книга и « и ручка». Нормализовать на уровне документа объединяет их, сохраняя полное текстовое содержимое.

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

Полный серверный общий модуль УчебныйДокументHTML85. Свой HTML создаётся строкой и разбирается в памяти, без браузера и внешних источников.

Подготовка

  1. Используйте отдельную учебную базу 8.5.1.1343. Создайте общий модуль УчебныйДокументHTML85: Сервер — Да, Клиент — Нет, Глобальный — Нет, Вызов сервера — Нет, Привилегированный — Нет.

  2. Вставьте весь приведённый модуль одного урока. В своей управляемой учебной обработке создайте команду и клиентский обработчик, вызывающий свою процедуру с директивой &НаСервереБезКонтекста. В её тело вставьте УчебныйДокументHTML85.ВыполнитьПример();.

  3. Источник HTML полностью записан в коде: свой вымышленный заказ, покупатель, книга, ручка и элементы с явно заданными id. ЧтениеHTML и ПостроительDOM получают строку, а не URL или внешний файл.

  4. Разбор HTML в этом уроке не открывает браузер, не отправляет форму, не загружает картинки и не исполняет JavaScript. Файлы, сеть, печать, рабочие документы и регистры не используются.

  5. Каждый запуск создаёт новый собственный документ в памяти. Поставьте точку останова перед конечными Сообщить и исследуйте Документ, его ЭлементДокумента и указанные переменные урока в серверном отладчике.

  6. ДокументHTML — корневой объект дерева, а его ЭлементДокумента, Тело и отдельный блок — другие узлы. Одинаковые имена методов не означают одинаковые правила допустимых дочерних узлов.

  7. Результаты ниже ожидаемые. В 1С код не запускался; статическая сверка сигнатур и readonly не подтверждает все особенности реализации HTML DOM вашей среды. Выполните проверки только на своём учебном стенде.

Процедура ВыполнитьПример() Экспорт
    HTML = "<html><head><title>Учебный заказ</title><meta id='meta' name='description' content='Вымышленный заказ'></head>
    |<body id='body'><p id='note'>Заказ существует только в памяти</p><pre id='code'>A-01: 3
    |B-02: 1</pre>
    |<form id='order' name='order' action='' method='get'>
    |<input id='customer' name='customer' type='text' value='Учебный покупатель'>
    |<input id='accepted' name='accepted' type='checkbox' value='yes'>
    |<button id='preview' name='preview' type='button' value='preview'>Предпросмотр</button></form>
    |<table id='items' summary='Книга и ручка'><caption id='caption'>Товары</caption><colgroup><col id='column'></colgroup><tbody>
    |<tr id='book'><td id='book-name'>Книга</td><td>3</td></tr><tr id='pen'><td>Ручка</td><td>1</td></tr>
    |</tbody></table><a id='help' name='help' href='#note'>Пояснение</a><img id='logo' alt='Учебная картинка без источника'>
    |</body></html>";
    Чтение = Новый ЧтениеHTML;
    Чтение.УстановитьСтроку(HTML);
    Попытка
        Построитель = Новый ПостроительDOM;
        Документ = Построитель.Прочитать(Чтение);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Документ) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Ожидался ДокументHTML, а не XML-документ";
    КонецЕсли;
    Форма = Документ.ПолучитьЭлементПоИдентификатору("order");
    Если Форма = Неопределено Тогда
        ВызватьИсключение "В своём HTML нужна форма order";
    КонецЕсли;
    Если ТипЗнч(Форма) <> Тип("ЭлементФормаHTML") Тогда
        ВызватьИсключение "order должен быть собственной HTML-формой";
    КонецЕсли;
    Блок = Документ.СоздатьЭлемент("div");
    Блок.УстановитьАтрибут("id", "own-work");
    Форма.ДобавитьДочерний(Блок);
    ПервыйТекст = Документ.СоздатьТекстовыйУзел("Книга");
    ВторойТекст = Документ.СоздатьТекстовыйУзел(" и ручка");
    Блок.ДобавитьДочерний(ПервыйТекст);
    Блок.ДобавитьДочерний(ВторойТекст);
    Если Блок.ДочерниеУзлы.Количество() <> 2 Тогда
        ВызватьИсключение "Ожидались два собственных соседних текста";
    КонецЕсли;
    До = Блок.ТекстовоеСодержимое;
    Документ.Нормализовать();
    Сообщить(До = "Книга и ручка");
    Сообщить(Блок.ТекстовоеСодержимое = До);
    Сообщить(Блок.ДочерниеУзлы.Количество() = 1);
    Сообщить(Блок.ПервыйДочерний.ЗначениеУзла = "Книга и ручка");

КонецПроцедуры

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

  1. Разобрать свою строку заказа и проверить реальный ТипЗнч ДокументHTML. Чтение закрывается как после успеха, так и при исключении построителя.

  2. Найти и проверить собственную форму order, создать блок div в том же документе и добавить его в эту форму. Это правка своего дерева в памяти, не страницы открытого браузера.

  3. Создать два текстовых узла через фабрику документа. Их строки задаются явно, поэтому исходное полное содержимое известно: Книга и ручка.

  4. Добавить оба текста в один блок и проверить число детей 2. Они соседние; между ними нет элемента или другого разделяющего узла.

  5. Сохранить полное текстовое содержимое до нормализации. Затем вызвать Нормализовать именно у ДокументHTML, чтобы обработать поддерево на всей глубине.

  6. Проверить число детей 1 и сохранение текста. Нормализация структуры не означает исчезновение второй части надписи.

  7. После нормализации пользоваться актуальными узлами из Блок.ДочерниеУзлы. Старая переменная ВторойТекст не гарантирует, что узел по-прежнему прикреплён к блоку.

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

  1. Четыре конечных сравнения должны дать Истина. Дочерних текстов стало один, надпись остаётся Книга и ручка.

  2. Вставьте между текстами свой элемент span: смежность нарушится. Нормализовать не обязано объединять тексты через этот элемент.

  3. Повторный вызов Нормализовать не должен менять нормализованную надпись. Не проверяйте сохранение идентичности второго исходного узла.

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

Соседние тексты собственного блока объединены на уровне документа с проверкой сохранности содержимого.

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

  1. Нормализация не является очисткой HTML от опасных тегов и не выполняет повторный разбор текстовой строки как разметки.

  2. Readonly ДочерниеУзлы нельзя присваивать заново. Меняем дерево методами, а не подменой коллекции.

  3. Создание текстового узла и создание элемента — разные операции; слово Книга здесь текст, не тег.

  4. Проверки нужно выполнить в своей 1С; этот урок не запускался.

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

Различить тот же HTML-документ и равную глубокую копию

Одна переменная ссылается на исходный документ, другая — на его глубокую копию. Проверяем идентичность и структурное равенство, затем меняем текст только в копии.

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

Полный серверный общий модуль УчебныйДокументHTML85. Свой HTML создаётся строкой и разбирается в памяти, без браузера и внешних источников.

Подготовка

  1. Используйте отдельную учебную базу 8.5.1.1343. Создайте общий модуль УчебныйДокументHTML85: Сервер — Да, Клиент — Нет, Глобальный — Нет, Вызов сервера — Нет, Привилегированный — Нет.

  2. Вставьте весь приведённый модуль одного урока. В своей управляемой учебной обработке создайте команду и клиентский обработчик, вызывающий свою процедуру с директивой &НаСервереБезКонтекста. В её тело вставьте УчебныйДокументHTML85.ВыполнитьПример();.

  3. Источник HTML полностью записан в коде: свой вымышленный заказ, покупатель, книга, ручка и элементы с явно заданными id. ЧтениеHTML и ПостроительDOM получают строку, а не URL или внешний файл.

  4. Разбор HTML в этом уроке не открывает браузер, не отправляет форму, не загружает картинки и не исполняет JavaScript. Файлы, сеть, печать, рабочие документы и регистры не используются.

  5. Каждый запуск создаёт новый собственный документ в памяти. Поставьте точку останова перед конечными Сообщить и исследуйте Документ, его ЭлементДокумента и указанные переменные урока в серверном отладчике.

  6. ДокументHTML — корневой объект дерева, а его ЭлементДокумента, Тело и отдельный блок — другие узлы. Одинаковые имена методов не означают одинаковые правила допустимых дочерних узлов.

  7. Результаты ниже ожидаемые. В 1С код не запускался; статическая сверка сигнатур и readonly не подтверждает все особенности реализации HTML DOM вашей среды. Выполните проверки только на своём учебном стенде.

Процедура ВыполнитьПример() Экспорт
    HTML = "<html><head><title>Учебный заказ</title><meta id='meta' name='description' content='Вымышленный заказ'></head>
    |<body id='body'><p id='note'>Заказ существует только в памяти</p><pre id='code'>A-01: 3
    |B-02: 1</pre>
    |<form id='order' name='order' action='' method='get'>
    |<input id='customer' name='customer' type='text' value='Учебный покупатель'>
    |<input id='accepted' name='accepted' type='checkbox' value='yes'>
    |<button id='preview' name='preview' type='button' value='preview'>Предпросмотр</button></form>
    |<table id='items' summary='Книга и ручка'><caption id='caption'>Товары</caption><colgroup><col id='column'></colgroup><tbody>
    |<tr id='book'><td id='book-name'>Книга</td><td>3</td></tr><tr id='pen'><td>Ручка</td><td>1</td></tr>
    |</tbody></table><a id='help' name='help' href='#note'>Пояснение</a><img id='logo' alt='Учебная картинка без источника'>
    |</body></html>";
    Чтение = Новый ЧтениеHTML;
    Чтение.УстановитьСтроку(HTML);
    Попытка
        Построитель = Новый ПостроительDOM;
        Документ = Построитель.Прочитать(Чтение);
    Исключение
        Чтение.Закрыть();
        ВызватьИсключение;
    КонецПопытки;
    Чтение.Закрыть();
    Если ТипЗнч(Документ) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Ожидался ДокументHTML, а не XML-документ";
    КонецЕсли;
    Документ.Нормализовать();
    ТаЖеСсылка = Документ;
    Копия = Документ.КлонироватьУзел(Истина);
    Если ТипЗнч(Копия) <> Тип("ДокументHTML") Тогда
        ВызватьИсключение "Ожидалась глубокая копия HTML-документа";
    КонецЕсли;
    Копия.Нормализовать();
    Сообщить(Документ.УзелИдентичен(ТаЖеСсылка));
    Сообщить(Не Документ.УзелИдентичен(Копия));
    Сообщить(Документ.УзелРавен(Копия));
    Сообщить(Документ.УзелРавен(Документ));
    ИсходноеПояснение = Документ.ПолучитьЭлементПоИдентификатору("note");
    ПояснениеКопии = Копия.ПолучитьЭлементПоИдентификатору("note");
    Если ИсходноеПояснение = Неопределено Или ПояснениеКопии = Неопределено Тогда
        ВызватьИсключение "В обеих собственных версиях нужно пояснение note";
    КонецЕсли;
    ИсходныйТекст = ИсходноеПояснение.ТекстовоеСодержимое;
    ПояснениеКопии.ТекстовоеСодержимое = "Изменена только учебная копия";
    Сообщить(ИсходноеПояснение.ТекстовоеСодержимое = ИсходныйТекст);
    Сообщить(Не Документ.УзелРавен(Копия));

КонецПроцедуры

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

  1. Создать свой исходный документ из строки и нормализовать его перед сравнением.

  2. Присваивание ТаЖеСсылка=Документ не копирует дерево. УзелИдентичен проверяет ссылку на тот же объект, а не сходство его текста.

  3. КлонироватьУзел(Истина) создаёт глубокую копию. Проверяем её тип перед использованием свойств документа.

  4. Нормализовать обе версии: по справке нормализация влияет на структурное равенство узлов.

  5. Исходный документ идентичен ТаЖеСсылка, не идентичен копии, но равен ей по структуре. Самому себе он также равен.

  6. Найти собственное пояснение note в каждой версии и проверить оба результата на Неопределено. Менять ТекстовоеСодержимое только найденного узла копии.

  7. Сохранность исходного текста показывает независимость глубокого дерева. После изменения копия уже структурно не равна оригиналу.

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

  1. Шесть конечных сравнений должны дать Истина: четыре до правки и два после неё.

  2. В отладчике оригинальное note сохраняет текст Заказ существует только в памяти, копия содержит новое пояснение.

  3. УзелИдентичен и УзелРавен отвечают на разные вопросы. Не используйте равенство текста как доказательство общего объекта.

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

Различие ссылочной идентичности и структурного равенства показано на полноценном собственном документе и его изменённой копии.

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

  1. УзелРавен не сравнивает пользовательские данные и не учитывает ряд служебных ссылок документа-владельца и родителей.

  2. Слово Истина в КлонироватьУзел относится к глубине копирования, не к записи документа в базу.

  3. Нельзя применять этот код к неизвестной странице пользователя: оба документа созданы в этом уроке.

  4. Никакой файл или окно браузера не изменяется; запуска в 1С не было.

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

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

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

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

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