Navigation

Navigation

Aspose.Words FOSS для .NET включает небольшой Nodes.Navigation пространство имён для итерации и позиционирования внутри дерева узлов документа: NodeEnumerator, тип перечислителя, лежащий в основе итерации в стиле for-each по дочерним узлам, и DocumentPositionMovement, перечисление, описывающее, как позиция одного узла соотносится с другим во время обхода. Это отличается от API манипуляций с деревом (вставка, удаление и реорганизация узлов), рассмотренных на Nodes странице — эта страница охватывает перемещение по дереву и сравнение позиций в уже существующем дереве.


Итерация дочерних узлов

Любой CompositeNode (базовый класс для контейнерных узлов, таких как Document, Section, Body и Paragraph) поддерживает итерацию в стиле for-each по своим непосредственным дочерним элементам через GetEnumerator(), который — согласно документации — обеспечивает поддержку итерации в стиле for-each по дочерним узлам узла. Возвращаемый перечислитель реализует IEnumerator<Node>; в этой оболочке API эту роль выполняет NodeEnumerator, который также реализует IDocumentPositionListener, чтобы отслеживать изменения позиции во время перечисления базового дерева. NodeEnumerator раскрывает стандартные члены Dispose() и Reset() вместе с контрактом IEnumerator<Node>.


Перемещение позиции документа

DocumentPositionMovement — это перечисление с шестью элементами: None, Inside, StartEnd, Sibling, Above и Below, которые описывают, как одна позиция в документе соотносится с другой при навигации по дереву: остаётся неизменной, перемещается внутрь узла, перемещается к границе начала/конца, перемещается к соседнему узлу или перемещается выше или ниже опорной позиции. Оно определено вместе с NodeEnumerator в той же области Nodes.Navigation оболочки API, отражая его роль в отслеживании изменений позиции во время перечисления.


Советы и лучшие практики

  • Используйте стандартный C# foreach над любым CompositeNode (или вызовите GetEnumerator() напрямую), чтобы пройти непосредственных потомков узла — перечислитель обрабатывает контракт IEnumerator<Node> за вас.
  • Поскольку NodeEnumerator также реализует IDocumentPositionListener, избегайте кэширования перечислителя между структурными изменениями дерева; получите его заново через GetEnumerator(), если коллекция узлов, по которой вы итерируетесь, изменилась.
  • Для глубоких обходов дерева (не только непосредственных потомков) используйте Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode), либо GetChildNodes(nodeType, isDeep) с установленным isDeep равным true, вместо ручного вложения перечислителей.

Общие проблемы

ПроблемаПричинаИсправление
Перебор дочерних узлов узла при их изменении вызывает исключения или пропускает узлыВо время перебора дерево было структурно измененоСначала соберите узлы в массив (например, с помощью NodeCollection.ToArray()), затем проходите по массиву, изменяя дерево
Неясно, как перемещённая позиция соотносится с оригинальнойЗначения DocumentPositionMovement не были провереныПроверьте полученный DocumentPositionMovement (Inside, StartEnd, Sibling, Above, Below или None), а не предполагайте конкретную связь

FAQ

Нужно ли мне использовать NodeEnumerator напрямую?

Обычно нет — стандартный C# foreach над CompositeNode использует его неявно через GetEnumerator(). Обращайтесь к нему напрямую только тогда, когда требуется явный контроль над Dispose()/Reset().

Что описывает DocumentPositionMovement?

Отношение между двумя позициями в дереве документа во время навигации — None, Inside, StartEnd, Sibling, Above или Below.

Чем это отличается от API манипуляций деревом на странице Nodes?

Этот Nodes Страница охватывает вставку, удаление, клонирование и реорганизацию узлов. Эта страница посвящена только чтению, обходу и позиционированию в уже существующем дереве.


API Reference Сводка

Класс / EnumОписание:
NodeEnumeratorIEnumerator<Node> / IDocumentPositionListener реализация за итерацией for-each; Dispose(), Reset()
DocumentPositionMovementШестичленный enum, описывающий относительное положение при обходе (None, Inside, StartEnd, Sibling, Above, Below)
CompositeNode.GetEnumerator()Возвращает enumerator для непосредственных дочерних узлов

См. также:

 Русский