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#
foreachover anyCompositeNode(or callGetEnumerator()directly) to walk a node’s immediate children — the enumerator handles theIEnumerator<Node>contract for you. - Because
NodeEnumeratoralso implementsIDocumentPositionListener, avoid caching an enumerator across structural edits to the tree; re-obtain it viaGetEnumerator()if the node collection you are iterating has changed. - For deep tree walks (not just immediate children), use
Node.NextPreOrder(rootNode)/PreviousPreOrder(rootNode), orGetChildNodes(nodeType, isDeep)withisDeepset totrue, rather than nesting enumerators manually.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
| Enumerating a node’s children while modifying them throws or skips nodes | The tree was structurally changed during enumeration | Collect 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 one | DocumentPositionMovement values were not inspected | Check 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 / Enum | Description |
|---|---|
NodeEnumerator | IEnumerator<Node> / IDocumentPositionListener implementation behind for-each iteration; Dispose(), Reset() |
DocumentPositionMovement | Six-member enum describing relative position during traversal (None, Inside, StartEnd, Sibling, Above, Below) |
CompositeNode.GetEnumerator() | Returns the enumerator for a node’s immediate children |