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