Выполняет переход к последнему потомку. Итератор перемещается к последнему потомку текущего узла, удовлетворяющему условиям отбора узлов.
Синтаксис
ПоследнийДочерний()Полное описание, параметры и ограничения
ОбходДереваDOM.ПоследнийДочерний (DOMTreeWalker.LastChild)
ОбходДереваDOM (DOMTreeWalker)
ПоследнийДочерний (LastChild)
Доступен, начиная с версии 8.1.
Синтаксис:
ПоследнийДочерний()
Возвращаемое значение:
Тип: АтрибутDOM, ДокументDOM, ЭлементDOM, ОпределениеТипаДокументаDOM, НотацияDOM, СущностьDOM, ФрагментДокументаDOM, ТекстDOM, КомментарийDOM, СекцияCDATADOM, ИнструкцияОбработкиDOM, СсылкаНаСущностьDOM, ПространствоИменXPath, Неопределено.
Если видимые потомки отсутствуют, то итератор не перемещается и возвращается Неопределено.
Описание:
Выполняет переход к последнему потомку. Итератор перемещается к последнему потомку текущего узла, удовлетворяющему условиям отбора узлов.
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Навигировать по DOM через родителя, детей и соседей
ОбходДереваDOM хранит текущую позицию. Последовательно перемещаем её и проверяем, какой именно узел выбран после каждого шага.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Документы и все узлы создаются в памяти на сервере. Внешние XML, DTD, сетевые схемы и файлы не загружаются.
Сначала оставьте учебные имена и значения неизменёнными. После контрольного запуска меняйте по одному условию.
Документ = Новый ДокументDOM("", "products");
Корень = Документ.ЭлементДокумента;
Для Номер = 1 По 2 Цикл
Товар = Документ.СоздатьЭлемент("product");
Товар.УстановитьАтрибут("code", ?(Номер = 1, "A-01", "B-02"));
Товар.ДобавитьДочерний(Документ.СоздатьТекстовыйУзел(?(Номер = 1, "Книга", "Ручка")));
Корень.ДобавитьДочерний(Товар);
КонецЦикла;
Обход = Документ.СоздатьОбходДерева(Корень, , Ложь);
Сообщить(Обход.Корень = Корень);
Сообщить(Обход.ТекущийУзел = Корень);
Сообщить(Не Обход.РаскрыватьСсылкиНаСущности);
ПервыйТовар = Обход.ПервыйДочерний();
Если ПервыйТовар = Неопределено Тогда
ВызватьИсключение "Нет первого товара в учебном дереве";
КонецЕсли;
Сообщить(ПервыйТовар.ПолучитьАтрибут("code") = "A-01");
ТекстКниги = Обход.ПоследнийДочерний();
Если ТекстКниги = Неопределено Тогда
ВызватьИсключение "Нет текста первого товара";
КонецЕсли;
Сообщить(ТекстКниги.ТекстовоеСодержимое = "Книга");
Сообщить(Обход.РодительскийУзел() = ПервыйТовар);
ВторойТовар = Обход.СледующийСоседний();
Если ВторойТовар = Неопределено Тогда
ВызватьИсключение "Нет второго товара";
КонецЕсли;
Сообщить(ВторойТовар.ПолучитьАтрибут("code") = "B-02");
Сообщить(Обход.ПредыдущийСоседний() = ПервыйТовар);
Обход.ТекущийУзел = Корень;
Сообщить(Обход.ПоследнийДочерний() = ВторойТовар);
Сообщить(Обход.ПредыдущийУзел() = ТекстКниги);
Сообщить(Обход.СледующийУзел() = ВторойТовар);
Обход.ТекущийУзел = Корень;
Сообщить(Обход.РодительскийУзел() = Неопределено);
Сообщить(Обход.ТекущийУзел = Корень);Разбор по шагам
Обход начинается на Корне. ПервыйДочерний переводит позицию на первого ребёнка и возвращает его.
Соседние перемещения остаются на одном уровне. РодительскийУзел возвращает на уровень выше внутри области обхода.
Присваивание ТекущийУзел явно меняет позицию. ПредыдущийУзел/СледующийУзел следуют порядку обхода всего дерева, не только соседей.
Выше корня области обход не выходит: попытка получить его родителя возвращает Неопределено, позиция остаётся на Корне.
Как проверить результат
ПервыйТовар имеет A-01, его текст Книга; следующий сосед имеет B-02.
ПредыдущийУзел от второго товара — текст первого; СледующийУзел возвращает на второй товар.
Все логические проверки Истина, в конце текущая позиция снова Корень.
Ожидаемый результат
На одном дереве отработаны направления навигации и явное восстановление позиции.
На что обратить внимание
Метод навигации меняет состояние обхода. Не считайте его простым чтением свойства без побочного эффекта.
Узел, возвращённый методом, может быть Неопределено на границе. Не обращайтесь к его данным без проверки.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Обойти дерево: ребёнок, сосед и родитель отличаются от индекса массива
В своём контейнере создаём три текста без пробелов между ними. ОбходДереваDOM перемещает текущую позицию, сохраняя заданный корень.
Где и как запускать
Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.
Подготовка
Используйте учебную базу платформы 8.5.1.1343 и серверную процедуру учебного общего модуля. Каждый пример выполняйте отдельно.
Все данные заказа вымышлены и находятся в строке. ЧтениеHTML разбирает данные, но не является браузером: форма не отправляется, ссылки не открываются, картинки не скачиваются.
Никакие файлы, адреса сайтов, токены и документы информационной базы не нужны. Не заменяйте учебную строку произвольным внешним HTML без отдельной проверки безопасности.
Индексы коллекций начинаются с нуля. Перед обращением к найденному узлу проверяйте Неопределено; перед специальными свойствами элемента проверяйте его тип.
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";
КонецЕсли;
Форма.ДобавитьДочерний(Блок);
Первый = Документ.СоздатьТекстовыйУзел("Книга");
Второй = Документ.СоздатьТекстовыйУзел(" / ");
Третий = Документ.СоздатьТекстовыйУзел("Ручка");
Блок.ДобавитьДочерний(Первый);
Блок.ДобавитьДочерний(Второй);
Блок.ДобавитьДочерний(Третий);
Обход = Документ.СоздатьОбходДерева(Блок);
Сообщить(Обход.Корень = Блок);
Сообщить(Обход.ПервыйДочерний() = Первый);
Сообщить(Обход.СледующийСоседний() = Второй);
Сообщить(Обход.ПредыдущийСоседний() = Первый);
Сообщить(Обход.РодительскийУзел() = Блок);
Сообщить(Обход.ПоследнийДочерний() = Третий);
Сообщить(Обход.ТекущийУзел = Третий);
Сообщить(Обход.СледующийСоседний() = Неопределено);
Сообщить(Обход.ТекущийУзел = Третий);
Обход.ТекущийУзел = Блок;
Сообщить(Обход.ПредыдущийУзел() = Неопределено);
Сообщить(Обход.СледующийУзел() = Первый);
Сообщить(Обход.ПредыдущийУзел() = Блок);
Сообщить("Раскрывать ссылки: " + Строка(Обход.РаскрыватьСсылкиНаСущности));
Сообщить("Фильтр: " + Строка(Обход.Фильтр));Разбор по шагам
Контейнер содержит ровно три текстовых узла, поэтому порядок не зависит от пробелов исходной HTML-строки.
Методы обхода перемещают ТекущийУзел, но не перемещают узлы дерева.
Когда соседа нет, возвращается Неопределено, а текущая позиция остаётся прежней.
Назначением ТекущийУзел возвращаемся в корень; обход не выходит к форме-родителю за его пределами.
Как проверить результат
Первые двенадцать сравнений Истина: корректная навигация и границы собственного контейнера.
Последние две строки показывают реальные настройки обхода; не обещаем определённого представления объекта фильтра.
Ожидаемый результат
Видна разница между последовательным обходом и навигацией по иерархии.
На что обратить внимание
Не обращайтесь к Данные у Неопределено на границе.
Чтение свойства Фильтр не превращает строковый JSON в объект ФильтрУзловDOM.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.