Объединить соседние текстовые узлы, сохранив текст пояснения

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

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

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

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Используйте учебную базу платформы 8.5.1.1343 и серверную процедуру учебного общего модуля. Каждый пример выполняйте отдельно.

  2. Все данные заказа вымышлены и находятся в строке. ЧтениеHTML разбирает данные, но не является браузером: форма не отправляется, ссылки не открываются, картинки не скачиваются.

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

  4. Индексы коллекций начинаются с нуля. Перед обращением к найденному узлу проверяйте Неопределено; перед специальными свойствами элемента проверяйте его тип.

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");
Если Форма = Неопределено Тогда
    ВызватьИсключение "Не найден учебный элемент order";
КонецЕсли;
Если ТипЗнч(Форма) <> Тип("ЭлементФормаHTML") Тогда
    ВызватьИсключение "Неожиданный тип учебного элемента order";
КонецЕсли;
Блок = Документ.СоздатьЭлемент("guide-section");
Если ТипЗнч(Блок) <> Тип("ЭлементHTML") Тогда
    ВызватьИсключение "Учебный контейнер должен иметь общий тип ЭлементHTML";
КонецЕсли;
Форма.ДобавитьДочерний(Блок);
Первый = Документ.СоздатьТекстовыйУзел("Книга");
Второй = Документ.СоздатьТекстовыйУзел(": 3");
Блок.ДобавитьДочерний(Первый);
Блок.ДобавитьДочерний(Второй);
Сообщить(Блок.ДочерниеУзлы.Количество() = 2);
Сообщить(Первый.СледующийСоседний = Второй);
Сообщить(Второй.ПредыдущийСоседний = Первый);
Блок.Нормализовать();
Сообщить(Блок.ДочерниеУзлы.Количество() = 1);
Сообщить(Блок.ТекстовоеСодержимое = "Книга: 3");
Сообщить(Блок.ПервыйДочерний = Блок.ПоследнийДочерний);

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

  1. Добавляем два собственных текста в новый пустой контейнер.

  2. До нормализации проверяем два узла и их взаимное соседство.

  3. Нормализовать объединяет соседний текст, а не суммы бизнес-данных.

  4. После операции повторно получаем узлы из дерева, не рассчитываем на сохранение прежних ссылок для всех реализаций.

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

  1. Все шесть сравнений дают Истина: 2 узла до операции, 1 после, текст Книга: 3 сохранён.

  2. Две строки таблицы товаров остались двумя строками — изменено только пояснение.

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

Разделены структура текстовых узлов и содержание пояснения.

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

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

  2. Ссылки на объединённые узлы не используйте как постоянные внешние идентификаторы.

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

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

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

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

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