Создает новый итератор по поддереву документа DOM, начиная с указанного узла. При создании итератор устанавливается на позицию перед указанным узлом. Метод соответствует интерфейсу NodeIterator стандарта W3C (Подробнее см. http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/traversal.html#Traversal-NodeIterator).
Синтаксис
СоздатьИтераторУзлов(<Узел>, <Отбор>, <ОбходитьСсылкиНаСущности>)Полное описание, параметры и ограничения
ДокументDOM.СоздатьИтераторУзлов (DOMDocument.CreateNodeIterator)
ДокументDOM (DOMDocument)
СоздатьИтераторУзлов (CreateNodeIterator)
Доступен, начиная с версии 8.1.
Синтаксис:
СоздатьИтераторУзлов(<Узел>, <Отбор>, <ОбходитьСсылкиНаСущности>)
Параметры:
<Узел> (обязательный)
Тип: АтрибутDOM, ДокументDOM, ЭлементDOM, ОпределениеТипаДокументаDOM, НотацияDOM, СущностьDOM, ФрагментДокументаDOM, ТекстDOM, КомментарийDOM, СекцияCDATADOM, ИнструкцияОбработкиDOM, СсылкаНаСущностьDOM, ПространствоИменXPath.
Узел DOM - стартовый узел итератора.
<Отбор> (необязательный)
Тип: ФильтрУзловDOM.
Отбор узлов DOM.
Если не указан, то будут проитерированы все узлы.
<ОбходитьСсылкиНаСущности> (необязательный)
Тип: Булево.
Признак обхода ссылок на сущности DOM.
Истина - при обходе узла ссылки на сущность будет производиться обход узлов содержимого сущности, в противном случае обход производиться не будет.
Значение по умолчанию: Истина.
Возвращаемое значение:
Тип: ИтераторУзловDOM.
Описание:
Создает новый итератор по поддереву документа DOM, начиная с указанного узла.
При создании итератор устанавливается на позицию перед указанным узлом.
Метод соответствует интерфейсу NodeIterator стандарта W3C (Подробнее см. http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/traversal.html#Traversal-NodeIterator).
Доступность:
Сервер, толстый клиент, внешнее соединение, мобильное приложение (сервер), мобильный автономный сервер.
Использование в версии:
Доступен, начиная с версии 8.1.
Методическая информация
Практические примеры
Начать обход с атрибута или отдельного фрагмента
Отбор атрибутов не добавляет их к обходу дочерних тегов: для этого урок задаёт сам атрибут корнем отдельного итератора.
Где и как запускать
Полный серверный общий модуль собственной учебной базы; работа с собственными DOM в памяти.
Подготовка
Собственная учебная база 8.5.1.1343. Создайте серверный общий модуль УчебныйОбходXML с флагом Сервер. Вставьте полный модуль одного урока и вызовите УчебныйОбходXML.ВыполнитьПример() из серверной команды собственной обработки.
Деревья создаются из фиксированных учебных данных. Нет чтения файлов, запросов сети, записей базы или произвольного внешнего XML.
Свойства ФильтрУзловDOM доступны только для чтения. Набор видов узлов задаётся параметрами конструктора, а не присваиванием ОтображатьЭлемент=Истина.
Параметры конструктора — значения перечисления ПараметрыОтбораУзловDOM, не Булево. Пустые позиции в коде оставляют соответствующие виды не включёнными согласно справке.
Подсчёт относится к дереву без форматирующих пробелов, построенному этим уроком. Запуск внутри 1С здесь ещё не подтверждён.
Процедура ВыполнитьПример() Экспорт
Документ = Новый ДокументDOM("", "products");
Корень = Документ.ЭлементДокумента;
Корень.УстановитьАтрибут("code", "A-01");
Атрибут = Корень.ПолучитьУзелАтрибута("code");
ФильтрАтрибута = Новый ФильтрУзловDOM(, , ПараметрыОтбораУзловDOM.ОтображатьАтрибут);
Сообщить(ФильтрАтрибута.ОтображатьАтрибут);
Атрибуты = СобратьУчебныеУзлы(Документ, Атрибут, ФильтрАтрибута);
Сообщить(Атрибуты.Количество() = 1);
Сообщить(Атрибуты[0] = Атрибут);
Сообщить(Атрибуты[0].Значение = "A-01");
Фрагмент = Документ.СоздатьФрагментДокумента();
Фрагмент.ДобавитьДочерний(Документ.СоздатьЭлемент("book"));
Фрагмент.ДобавитьДочерний(Документ.СоздатьЭлемент("pen"));
ФильтрФрагмента = Новый ФильтрУзловDOM(, ПараметрыОтбораУзловDOM.ОтображатьЭлемент, , , , , , , , , , ПараметрыОтбораУзловDOM.ОтображатьФрагментДокумента);
Сообщить(ФильтрФрагмента.ОтображатьФрагментДокумента);
Сообщить(ФильтрФрагмента.ОтображатьЭлемент);
Узлы = СобратьУчебныеУзлы(Документ, Фрагмент, ФильтрФрагмента);
Сообщить(Узлы.Количество() = 3);
Сообщить(Узлы[0] = Фрагмент);
Сообщить(Узлы[1].ИмяУзла = "book");
Сообщить(Узлы[2].ИмяУзла = "pen");
Сообщить(Корень.ДочерниеУзлы.Количество() = 0);
КонецПроцедуры
Функция СобратьУчебныеУзлы(Документ, Корень, Фильтр)
Результат = Новый Массив;
Итератор = Документ.СоздатьИтераторУзлов(Корень, Фильтр, Ложь);
ОшибкаОбхода = "";
Попытка
Узел = Итератор.СледующийУзел();
Пока Узел <> Неопределено Цикл
Результат.Добавить(Узел);
Узел = Итератор.СледующийУзел();
КонецЦикла;
Исключение
ОшибкаОбхода = ОписаниеОшибки();
КонецПопытки;
ОшибкаЗавершения = "";
Попытка
Итератор.Отсоединить();
Исключение
ОшибкаЗавершения = ОписаниеОшибки();
КонецПопытки;
Если Не ПустаяСтрока(ОшибкаОбхода) Или Не ПустаяСтрока(ОшибкаЗавершения) Тогда
ВызватьИсключение ОшибкаОбхода + " " + ОшибкаЗавершения;
КонецЕсли;
Возврат Результат;
КонецФункцииРазбор по шагам
Атрибут code принадлежит products, но не содержится в его ДочерниеУзлы. Передаём реальный АтрибутDOM как самостоятельный корень.
Фильтр атрибута оставляет в результате один атрибут. Его значение A-01 читаем после проверки количества.
Отдельный ФрагментДокументаDOM принадлежит тому же документу и содержит book/pen. Фрагмент ещё не вставлен в products.
Второй фильтр включает фрагмент и элементы, поэтому возвращаются сам фрагмент и два его ребёнка.
Последнее сравнение доказывает, что обход не переместил фрагмент в корень документа.
Как проверить результат
Одиннадцать проверок ожидаются Истина: четыре для атрибута и семь для фрагмента/неизменности корня.
Фрагмент остаётся отдельным контейнером; в products нет новых дочерних тегов.
Ожидаемый результат
Показано применение двух специальных видов отбора с настоящими корнями, а не ожиданием атрибутов среди детей.
На что обратить внимание
Добавление фрагмента в другой узел перемещает его детей, поэтому это другая операция и другой результат.
Не путать значение АтрибутDOM со значением ФильтрУзловDOM: типы создаются разными API.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.
Отобрать документ, DOCTYPE и узлы собственных объявлений DTD
Используем фиксированный внутренний DTD: документ и тип документа обходятся вместе, сущность и нотация — от своих отдельных корней.
Где и как запускать
Полный серверный общий модуль собственной учебной базы; работа с собственными DOM в памяти.
Подготовка
Собственная учебная база 8.5.1.1343. Создайте серверный общий модуль УчебныйОбходXML с флагом Сервер. Вставьте полный модуль одного урока и вызовите УчебныйОбходXML.ВыполнитьПример() из серверной команды собственной обработки.
Деревья создаются из фиксированных учебных данных. Нет чтения файлов, запросов сети, записей базы или произвольного внешнего XML.
Свойства ФильтрУзловDOM доступны только для чтения. Набор видов узлов задаётся параметрами конструктора, а не присваиванием ОтображатьЭлемент=Истина.
Параметры конструктора — значения перечисления ПараметрыОтбораУзловDOM, не Булево. Пустые позиции в коде оставляют соответствующие виды не включёнными согласно справке.
Подсчёт относится к дереву без форматирующих пробелов, построенному этим уроком. Запуск внутри 1С здесь ещё не подтверждён.
XML содержит только собственный внутренний DTD. Внешнего подмножества DOCTYPE нет, SYSTEM/PUBLIC в двух объявлениях — учебные URN, не пути и не HTTP-адреса.
guideIcon — неразбираемая сущность NDATA; она объявлена, но не используется как &guideIcon; в тексте. Её ресурс не загружается. Нотация описывает формат, не изображение.
Параметры и построитель создаются заново для этой известной строки. Никогда не переносите разрешение DTD на произвольный XML из интернета или API.
Процедура ВыполнитьПример() Экспорт
Параметры = Новый ПараметрыЧтенияXML(, , , , , Ложь);
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку("<?xml version=""1.0""?>
|<!DOCTYPE products [
|<!NOTATION guideMark PUBLIC ""guide-marker"" ""urn:guide:marker-format"">
|<!ENTITY guideIcon SYSTEM ""urn:guide:marker-payload"" NDATA guideMark>
|]>
|<products xmlns:g=""urn:guide:dtd""><product>Книга</product></products>", Параметры);
Построитель = Новый ПостроительDOM;
Настройки = Построитель.КонфигурацияDOM;
Если НЕ Настройки.ВозможноУстановитьПараметр("disallow-doctype", Ложь) Тогда
Чтение.Закрыть();
ВызватьИсключение "Построитель не разрешает собственный внутренний DTD";
КонецЕсли;
Настройки.УстановитьПараметр("disallow-doctype", Ложь);
Попытка
Документ = Построитель.Прочитать(Чтение);
Исключение
Чтение.Закрыть();
ВызватьИсключение;
КонецПопытки;
Чтение.Закрыть();
ОписаниеТипа = Документ.ОпределениеТипаДокумента;
Если ОписаниеТипа = Неопределено Тогда
ВызватьИсключение "Включите чтение типа документа, не подменяйте его пустым новым DOCTYPE";
КонецЕсли;
Сущность = ОписаниеТипа.Сущности.ПолучитьИменованныйЭлемент("guideIcon");
Нотация = ОписаниеТипа.Нотации.ПолучитьИменованныйЭлемент("guideMark");
Если ТипЗнч(Сущность) <> Тип("СущностьDOM") ИЛИ ТипЗнч(Нотация) <> Тип("НотацияDOM") Тогда
ВызватьИсключение "Построитель не сохранил ожидаемые собственные объявления DTD";
КонецЕсли;
Узлы = Новый Массив;
Узлы.Добавить(Сущность);
Узлы.Добавить(Нотация);
ФильтрДокумента = Новый ФильтрУзловDOM(, , , , , , , , , ПараметрыОтбораУзловDOM.ОтображатьДокумент, ПараметрыОтбораУзловDOM.ОтображатьОпределениеТипаДокумента);
Сообщить(ФильтрДокумента.ОтображатьДокумент);
Сообщить(ФильтрДокумента.ОтображатьОпределениеТипаДокумента);
ДокументИТип = СобратьУчебныеУзлы(Документ, Документ, ФильтрДокумента);
Сообщить(ДокументИТип.Количество() = 2);
Сообщить(ДокументИТип[0] = Документ);
Сообщить(ДокументИТип[1] = ОписаниеТипа);
ФильтрОбъявлений = Новый ФильтрУзловDOM(, , , , , , ПараметрыОтбораУзловDOM.ОтображатьСущность, , , , , , ПараметрыОтбораУзловDOM.ОтображатьНотацию);
Сообщить(ФильтрОбъявлений.ОтображатьСущность);
Сообщить(ФильтрОбъявлений.ОтображатьНотацию);
Для Каждого Узел Из Узлы Цикл
Объявление = СобратьУчебныеУзлы(Документ, Узел, ФильтрОбъявлений);
Сообщить(Объявление.Количество() = 1);
Сообщить(Объявление[0] = Узел);
КонецЦикла;
Ссылка = Документ.СоздатьСсылкуНаСущность("guideDetached");
ФильтрСсылки = Новый ФильтрУзловDOM(, , , , , ПараметрыОтбораУзловDOM.ОтображатьСсылкуНаСущность);
Сообщить(ФильтрСсылки.ОтображатьСсылкуНаСущность);
Ссылки = СобратьУчебныеУзлы(Документ, Ссылка, ФильтрСсылки);
Сообщить(Ссылки.Количество() = 1);
Сообщить(Ссылки[0] = Ссылка);
Сообщить(Документ.ЭлементДокумента.ТекстовоеСодержимое = "Книга");
КонецПроцедуры
Функция СобратьУчебныеУзлы(Документ, Корень, Фильтр)
Результат = Новый Массив;
Итератор = Документ.СоздатьИтераторУзлов(Корень, Фильтр, Ложь);
ОшибкаОбхода = "";
Попытка
Узел = Итератор.СледующийУзел();
Пока Узел <> Неопределено Цикл
Результат.Добавить(Узел);
Узел = Итератор.СледующийУзел();
КонецЦикла;
Исключение
ОшибкаОбхода = ОписаниеОшибки();
КонецПопытки;
ОшибкаЗавершения = "";
Попытка
Итератор.Отсоединить();
Исключение
ОшибкаЗавершения = ОписаниеОшибки();
КонецПопытки;
Если Не ПустаяСтрока(ОшибкаОбхода) Или Не ПустаяСтрока(ОшибкаЗавершения) Тогда
ВызватьИсключение ОшибкаОбхода + " " + ОшибкаЗавершения;
КонецЕсли;
Возврат Результат;
КонецФункцииРазбор по шагам
Фиксированный XML разрешает только собственный внутренний DTD. Неразбираемая guideIcon NDATA и нотация guideMark существуют в коллекциях объявлений; их URN не загружаются.
Первый фильтр включает ДокументDOM и ОпределениеТипаДокументаDOM, но не теги/текст. Итератор от документа возвращает именно документ и его DOCTYPE.
Сущности и нотации находятся в специальных коллекциях, не в обычных дочерних тегах. Для каждого реального объявления создаём отдельный обход от него самого.
СоздатьСсылкуНаСущность создаёт отдельный, не вставленный в документ узел guideDetached. Это не ссылка на NDATA-ресурс и не загрузка файла; её содержимое не обходится, третий аргумент итератора Ложь.
ОтображатьСсылкуНаСущность выбирает вид узла, а ОбходитьСсылкиНаСущности управляет обходом его содержимого. Эти параметры не одно и то же.
Все readonly-флаги проверяются у созданных фильтров. Из текста документа по-прежнему получается только Книга.
Как проверить результат
Пятнадцать логических проверок ожидаются Истина: пять для документа/DOCTYPE, шесть для двух объявлений, три для отдельной ссылки и одна для исходного текста.
Внешние схемы/файлы не запрашиваются; отдельно созданная ссылка не вставлена и не сериализуется в исходный XML.
Если построитель не сохранил реальные объявления, урок останавливается, не подменяет их фиктивными объектами.
Ожидаемый результат
Показаны пять редких видов DOM-фильтра на собственных реальных узлах, с правильными отдельными корнями.
На что обратить внимание
Не разрешать DTD для неизвестного входного XML из API или интернета.
Нельзя вставлять неразбираемую сущность NDATA как обычное текстовое содержимое через &guideIcon;.
Отбор ссылки не доказывает наличие раскрытого содержимого сущности.
Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.