Navigation

Navigation

Aspose.Words FOSS for .NET includes a small Nodes.Navigation namespace for iterating and positioning within a document’s node tree: NodeEnumerator, the enumerator type behind for-each style iteration over child nodes, and DocumentPositionMovement, an enumeration describing how one node’s position relates to another during traversal. This is distinct from the tree-manipulation APIs (inserting, removing, and reorganizing nodes) covered on the Nodes page — this page covers moving through and comparing positions in a tree that already exists.


Iterating Child Nodes

Any CompositeNode (the base class for container nodes such as Document, Section, Body, and Paragraph) supports for-each style iteration over its immediate children via GetEnumerator(), which — per its documentation — provides support for the for-each style of iteration over the child nodes of a node. The enumerator returned implements IEnumerator<Node>; in this API surface, that role is filled by NodeEnumerator, which also implements IDocumentPositionListener so it can track position changes while the underlying tree is being enumerated. NodeEnumerator exposes the standard Dispose() and Reset() members alongside the IEnumerator<Node> contract.


Document Position Movement

DocumentPositionMovement is an enumeration with six members — None, Inside, StartEnd, Sibling, Above, and Below — representing how one position in the document relates to another as the tree is navigated: whether it is unchanged, moved inside a node, moved to a start/end boundary, moved to a sibling, or moved above or below the reference position. It is defined alongside NodeEnumerator in the same Nodes.Navigation area of the API surface, reflecting its role in tracking position changes during enumeration.


Tips and Best Practices

  • Use a standard C# foreach over any CompositeNode (or call GetEnumerator() directly) to walk a node’s immediate children — the enumerator handles the IEnumerator<Node> contract for you.
  • Because NodeEnumerator also implements IDocumentPositionListener, avoid caching an enumerator across structural edits to the tree; re-obtain it via GetEnumerator() if the node collection you are iterating has changed.
  • For deep tree walks (not just immediate children), use Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode), or GetChildNodes(nodeType, isDeep) with isDeep set to true, rather than nesting enumerators manually.

Common Issues

IssueCauseFix
Enumerating a node’s children while modifying them throws or skips nodesThe tree was structurally changed during enumerationCollect the nodes into an array first (for example with NodeCollection.ToArray()), then iterate the array while modifying the tree
Unsure how a moved position relates to the original oneDocumentPositionMovement values were not inspectedCheck the reported DocumentPositionMovement (Inside, StartEnd, Sibling, Above, Below, or None) rather than assuming a specific relationship

FAQ

Do I need to use NodeEnumerator directly?

Not usually — standard C# foreach over a CompositeNode uses it implicitly through GetEnumerator(). Reach for it directly only when you need explicit control over Dispose()/Reset().

What does DocumentPositionMovement describe?

The relationship between two positions in the document tree during navigation — None, Inside, StartEnd, Sibling, Above, or Below.

How is this different from the tree-manipulation APIs on the Nodes page?

The Nodes page covers inserting, removing, cloning, and reorganizing nodes. This page covers read-only traversal and positioning within a tree that already exists.


API Reference Summary

Class / EnumDescription
NodeEnumeratorIEnumerator<Node> / IDocumentPositionListener implementation behind for-each iteration; Dispose(), Reset()
DocumentPositionMovementSix-member enum describing relative position during traversal (None, Inside, StartEnd, Sibling, Above, Below)
CompositeNode.GetEnumerator()Returns the enumerator for a node’s immediate children

See Also