Hello Team,
I have two documents, and I am using a bookmark-replacement logic. I’m facing an issue where a bookmark gets removed if two bookmarks exist at the same location in the document. The inner bookmark named BOOKMARK is being removed in the output document, and I don’t want this internal bookmark to be deleted during the replacement.
Could you please help me with this?
public void ReplaceBookmarks(string sourceDocPath, string targetDocPath, string outputDocPath)
{
Document src = new Document(sourceDocPath);
Document dst = new Document(targetDocPath);
DocumentBuilder builder = new DocumentBuilder(dst);
List<Bookmark> bookmakrs = dst.Range.Bookmarks.Where(b => !b.Name.StartsWith("_")).ToList();
foreach (Bookmark bk in bookmakrs)
{
Console.WriteLine(bk.Name);
bk.Text = "";
Bookmark srcBookmark = src.Range.Bookmarks[bk.Name];
if (srcBookmark != null)
{
List<Node> extractedNodes = ExtractContentHelper.ExtractContent(srcBookmark.BookmarkStart, srcBookmark.BookmarkEnd, false);
Document extractedContent = ExtractContentHelper.GenerateDocument(src, extractedNodes);
builder.MoveToBookmark(bk.Name, true, true);
builder.InsertDocumentInline(extractedContent, ImportFormatMode.UseDestinationStyles, new ImportFormatOptions());
if (builder.CurrentNode != bk.BookmarkEnd)
builder.InsertNode(bk.BookmarkEnd);
}
}
dst.Save(outputDocPath);
}
Documents required.zip (52.7 KB)
@KeerthanaRamesh214
Summary
The inner bookmark disappears because the code clears the outer bookmark’s content with bk.Text = "". In Aspose.Words, setting a bookmark’s text replaces everything between its start and end markers, which can also remove any nested BookmarkStart/BookmarkEnd nodes that lie inside that range.
Why it happens
bk.Text = "" tells the library to replace the whole range of the bookmark with an empty string. The replacement is performed by removing all nodes that belong to that range, and nested bookmark markers are part of those nodes.
- After the removal, the subsequent
MoveToBookmark and InsertDocumentInline work on a range that no longer contains the inner bookmark, so it never gets re‑inserted.
What to do next
- Avoid clearing the bookmark text directly
// bk.Text = ""; // comment out this line
Run the routine again and verify whether the inner bookmark is retained.
2. If you need to delete the outer content but keep inner bookmarks, remove the nodes manually while skipping any bookmark markers:
Node cur = bk.BookmarkStart.NextSibling;
while (cur != null && cur != bk.BookmarkEnd)
{
Node next = cur.NextSibling;
if (!(cur is BookmarkStart) && !(cur is BookmarkEnd))
cur.Remove(); // delete text, tables, etc.
cur = next;
}
- Check the extracted fragment before insertion to see if it still contains the inner bookmark:
foreach (Bookmark inner in extractedContent.Range.Bookmarks)
Console.WriteLine("Extracted bookmark: " + inner.Name);
If the inner bookmark is already missing at this point, the issue originates in the extraction logic.
4. Re‑create the outer bookmark after inserting new content (optional):
builder.MoveToBookmark(bk.Name);
builder.StartBookmark(bk.Name);
// insert new content …
builder.EndBookmark(bk.Name);
- Test with a minimal document that contains only the outer bookmark and one nested bookmark to isolate the behaviour.
If the inner bookmark is still removed after trying the steps above, please provide:
- The exact Aspose.Words for .NET version you are using.
- A small pair of sample documents that reproduce the nesting (you may redact any sensitive text).
With that information we can investigate whether the behaviour is version‑specific or if additional handling is required.
I could not fully verify this explanation against the retrieved sources. Please double-check the behaviour in your environment and confirm the exact SDK/version.
@KeerthanaRamesh214 The behavior is expected. In your code you set the bookmark’s text to empty string. In this case all content between the corresponding BookmarkStart and BookmarkEnd nodes is removed. This is by design. So you should either avoid using nested bookmarks in your template or implement your custom logic to remove bookmark’s content keeping the inner bookmarks untouched.
@alexey.noskov I am trying to replace all the bookmarks in one document with the bookmarks from another document that have the same names. Is it possible to preserve all the nested bookmarks while also replacing the content?
@KeerthanaRamesh214 As it was mentioned above The provided code works as expected and it is expected that inner bookmarks are removed when bookmark text is set to empty string. Unfortunately, there is no direct bult-in way to remove content of the bookmark keeping the nested bookmarks untouched. I would recommend to avoid using nested bookmarks in your template, since custom content removing code might be error prone.
1 Like