Bookmarks
Bookmarks
This guide shows how to read, insert, navigate to, and remove bookmarks in a Word document with Aspose.Words FOSS for .NET. A bookmark marks a named location or range of content so it can be looked up, navigated to, or used as an insertion point for further edits. Aspose.Words FOSS for .NET represents bookmarks with the Bookmark, BookmarkStart, and BookmarkEnd classes, and provides DocumentBuilder methods for creating and locating them while authoring or editing a document.
Reading Bookmarks
Every Range exposes the bookmarks it contains through the Bookmarks property, which returns a BookmarkCollection. Since Document itself exposes a Range, doc.Range.Bookmarks returns every bookmark in the document. Look up a specific bookmark by name with the BookmarkCollection indexer — bookmarks[bookmarkName] — check how many exist with Count, or walk the whole collection with GetEnumerator(). Each Bookmark exposes its Name and the text it encloses through Text.
Inserting Bookmarks with DocumentBuilder
DocumentBuilder is the usual way to create bookmarks while writing a document. Call StartBookmark(bookmarkName) before inserting content, then EndBookmark(bookmarkName) after it — the builder wraps everything written in between as the bookmarked range. For a range of table columns, use StartColumnBookmark(bookmarkName) and EndColumnBookmark(bookmarkName) instead; the resulting Bookmark.IsColumn is true, with FirstColumn and LastColumn identifying the marked column range. To reposition the builder at an existing bookmark for further edits, call MoveToBookmark(bookmarkName), or the overload MoveToBookmark(bookmarkName, isStart, isAfter) to control which end of the bookmark the cursor lands on.
Bookmark Structure in the Document Tree
A bookmark is represented in the document tree as a pair of nodes: BookmarkStart and BookmarkEnd, both constructed as BookmarkStart(doc, name) / BookmarkEnd(doc, name). Each links back to its logical Bookmark object — BookmarkStart.Bookmark returns it, and Bookmark in turn exposes BookmarkStart and BookmarkEnd properties pointing at its two boundary nodes. Because BookmarkStart and BookmarkEnd are ordinary nodes, they support the standard node operations such as GetText(), Clone(isCloneChildren), and GetAncestor(ancestorType), and can be located by walking the tree like any other node type.
Removing Bookmarks
Call Bookmark.Remove() to delete a single bookmark’s start and end markers — this removes the bookmark itself, not the document content it encloses. To remove bookmarks in bulk, use BookmarkCollection.Remove(bookmark), Remove(bookmarkName), RemoveAt(index), or Clear() to drop every bookmark in the range at once.
Tips and Best Practices
- Prefer the
BookmarkCollectionindexer (bookmarks["BookmarkName"]) over manual iteration when you already know the target bookmark’s name. - Always pair a
StartBookmark(name)call with a matchingEndBookmark(name)call using the same name — an unmatched pair leaves the bookmark incomplete. - Check
Bookmark.IsColumnbefore readingFirstColumnorLastColumn— those two properties are only meaningful for column bookmarks created withStartColumnBookmark/EndColumnBookmark. Bookmark.Remove()deletes only the bookmark markers, not the enclosed text, so removing a bookmark never deletes document content.- Use
DocumentBuilder.MoveToBookmark()to jump the builder’s cursor to a known location instead of manually searching the node tree for aBookmarkStart.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
BookmarkCollection indexer returns null for a name lookup | The bookmark name doesn’t exist in the range being searched | List names first via GetEnumerator() to confirm the exact, case-sensitive name |
| Inserted content isn’t bookmarked | EndBookmark() was never called, or was called with a different name than StartBookmark() | Always match StartBookmark(name) with EndBookmark(name) using the identical name string |
| Column bookmark data looks wrong | FirstColumn/LastColumn read without checking IsColumn first | Only interpret FirstColumn/LastColumn when Bookmark.IsColumn is true |
FAQ
How do I get every bookmark in a document?
Read doc.Range.Bookmarks, which returns a BookmarkCollection covering the whole document.
Can I bookmark part of a table by column instead of by text range?
Yes — use DocumentBuilder.StartColumnBookmark(bookmarkName) and EndColumnBookmark(bookmarkName). The resulting bookmark has IsColumn set to true, with FirstColumn/LastColumn marking the column range.
Does removing a bookmark delete the text it marks?
No. Bookmark.Remove() removes only the BookmarkStart/BookmarkEnd marker nodes; the document content in between is left untouched.
How do I move the DocumentBuilder cursor to an existing bookmark?
Call DocumentBuilder.MoveToBookmark(bookmarkName), or MoveToBookmark(bookmarkName, isStart, isAfter) to control whether the cursor lands at the start or end of the bookmark.
What’s the difference between the BookmarkCollection.Remove() overloads?
Remove(bookmark) takes a Bookmark object, Remove(bookmarkName) takes its name, and RemoveAt(index) takes its position in the collection — all three remove a single bookmark, while Clear() removes every bookmark in the collection.
API Reference Summary
| Class / Method | Description |
|---|---|
Bookmark | Represents a single bookmark; exposes Name, Text, IsColumn, FirstColumn, LastColumn, and Remove() |
BookmarkCollection | Bookmarks in a Range; indexer by name, Remove(), RemoveAt(), Clear(), Count |
BookmarkStart / BookmarkEnd | Document nodes marking a bookmark’s boundaries; link back via Bookmark.BookmarkStart/Bookmark.BookmarkEnd |
Range.Bookmarks | Returns the BookmarkCollection for a given range, including doc.Range.Bookmarks for the whole document |
DocumentBuilder.StartBookmark() / EndBookmark() | Wrap inserted content in a named bookmark |
DocumentBuilder.StartColumnBookmark() / EndColumnBookmark() | Mark a range of table columns as a bookmark |
DocumentBuilder.MoveToBookmark() | Positions the builder’s cursor at an existing bookmark |