How to remove a bookmark and its content

Hi,

We try the function “RemoveBookmarkWithContent” posted in the forum, it works fine but in a certain context it doesn’t.
Could you have a look to the file attached.
When you try to delete the bookmark “ChLaboAgr” and its content, the paragraph containing the field “imgCertificat” is also deleted.

Do you have an idea ?

Thank you for your help

Emmanuel

Hi
Thanks for your request. It removes content between BookmarkStart and BookmarkEnd. If you open your document using MS Word and move to bookmark the you will see that both paragraphs are elected so these paragraphs are placed between BookmarkStart and BookmarkEnd. You can also check this using DocumentExplorer (Aspose.Words demo app).
Best regards.

Hi again.
I also try to remove content of bookmark using the following code and field “imgCertificat” was not removed.

Document doc = new Document(@"Test177\in.doc");
doc.Range.Bookmarks["ChLaboAgr"].Text = string.Empty;
doc.Save(@"Test177\out.doc");

Could you please provide me your code?
Best regards.

Thank you for your reply and you help

This is the code found on your forum
The nodes between Start and End of bookmark may be also Start or End from other bookmark. It’s in this case I have to use this kind of code.

#Region "routines"
Private BookmarkNodes As ArrayList

Private Sub RemoveBookmarkWithContent(ByVal bookmark As Bookmark)
’ We need to store other bookmark nodes here, to move them away from the removed area.
Dim bookmarkNames As Hashtable = New Hashtable
Dim bookmarkStarts As Hashtable = New Hashtable
Dim bookmarkEnds As Hashtable = New Hashtable

Dim nodesToRemove As ArrayList = New ArrayList

Dim bookmarkStart As BookmarkStart = bookmark.BookmarkStart
Dim bookmarkEnd As BookmarkEnd = bookmark.BookmarkEnd
Dim node As Node = bookmarkStart
Dim doc As Document = node.Document
Dim lastParagraph As Paragraph = doc.LastSection.Body.LastParagraph

’ Bookmark nodes located immediately before start of our bookmark should also be included in the removal process.
Do
node = node.PreviousPreOrder(doc)
Loop While IsBookmarkNode(node)

’ Look back from the bookmark start node to include containing nodes into removal process.
Do While node.IsComposite
Dim prevNode As Node = node.PreviousPreOrder(doc)

If prevNode Is Nothing Then
Exit Do
Else
node = prevNode
End If
Loop

’ Find the paragraph that is next to removed bookmark range.
’ It will be used to move all bookmark start/end nodes belonging to bookmarks overlapping our bookmark,
’ so that they will be preserved after this bookmark removal.
Dim endPara As Paragraph

’ It can be the paragraph containing bookmark end node if the last paragraph in the bookmark range 
’ contains other nodes beside BookmarkEnd or is the last unremovable paragraph in the document.
If Not bookmarkEnd.NextSibling Is Nothing OrElse bookmarkEnd.ParentNode Is lastParagraph Then
endPara = CType(bookmarkEnd.ParentNode, Paragraph)
’ Or it can be the paragraph next to it.
Else
Do While node.NodeType <> NodeType.Paragraph
node = node.NextPreOrder(doc)
Loop

endPara = CType(node, Paragraph)
End If

’ Iterate over all nodes that contain or are between bookmark start and end nodes.
Do While Not node Is bookmarkEnd
node = node.NextPreOrder(doc)

’ BookmarkStart/BookmarkEnd are saved to be handled separately later.
’ All other nodes are collected as candidates for removal.
If (Not StoreIfBookmark(bookmarkNames, bookmarkStarts, bookmarkEnds, node)) Then
nodesToRemove.Add(node)
End If
Loop

For Each name As String In bookmarkNames.Keys
If (bookmarkStarts.ContainsKey(name)) AndAlso (bookmarkEnds.ContainsKey(name)) Then
’ If bookmark is nested, remove it altogether.
RemoveBookmarkNode(name, bookmarkStarts)
RemoveBookmarkNode(name, bookmarkEnds)
Else
’ If bookmark is overlapping, move the contained start/end node to the next paragraph after removed range.
If bookmarkStarts.ContainsKey(name) Then
MoveBookmarkNode(name, bookmarkStarts, endPara)
Else
MoveBookmarkNode(name, bookmarkEnds, endPara)
End If
End If
Next name

Dim hasNodesToRemove As Boolean = True

Do While hasNodesToRemove

hasNodesToRemove = False

Dim i As Integer = 0

Do While i < nodesToRemove.Count
Dim nodeToRemove As Node = CType(nodesToRemove(i), Node)
’ Skip already removed nodes.
’ Skip nodes that have child nodes.
’ Do not remove node if it is the last paragraph in the document.
If Not (nodeToRemove.ParentNode Is Nothing) And _
Not (nodeToRemove.IsComposite AndAlso CType(nodeToRemove, CompositeNode).HasChildNodes) And _
Not (nodeToRemove Is lastParagraph) Then
’ Remove node.
nodeToRemove.Remove()
’ If at least one node was removed in loop, then the loop will be repeated.
hasNodesToRemove = True
End If
i += 1
Loop
Loop
End Sub

Private Function IsBookmarkNode(ByVal node As Node) As Boolean
Return (node.NodeType = NodeType.BookmarkStart) OrElse (node.NodeType = NodeType.BookmarkEnd)
End Function

Private Function StoreIfBookmark(ByVal bookmarkNames As Hashtable, ByVal bookmarkStarts As Hashtable, ByVal bookmarkEnds As Hashtable, ByVal node As Node) As Boolean
Try
If node.NodeType = NodeType.BookmarkStart Then
Dim bookmarkStart As BookmarkStart = CType(node, BookmarkStart)
bookmarkNames(bookmarkStart.Name) = Nothing
bookmarkStarts.Add(bookmarkStart.Name, bookmarkStart)
Return True
ElseIf node.NodeType = NodeType.BookmarkEnd Then
Dim bookmarkEnd As BookmarkEnd = CType(node, BookmarkEnd)
bookmarkNames(bookmarkEnd.Name) = Nothing
bookmarkEnds.Add(bookmarkEnd.Name, bookmarkEnd)
Return True
End If

Catch ex As Exception

End Try

Return False
End Function

Private Function RemoveBookmarkNode(ByVal name As String, ByVal bookmarkNodes As Hashtable) As Node
Dim node As Node = CType(bookmarkNodes(name), Node)
node.Remove()
bookmarkNodes.Remove(name)
Return node
End Function

Private Sub MoveBookmarkNode(ByVal name As String, ByVal bookmarkNodes As Hashtable, ByVal para As Paragraph)
para.PrependChild(RemoveBookmarkNode(name, bookmarkNodes))
End Sub

#End Region

Emmanuel

Hi
Thank you for additional information. Please try using the following code to remove bookmark with its content.

doc.Range.Bookmarks("ChLaboAgr").Text = String.Empty
doc.Range.Bookmarks("ChLaboAgr").BookmarkStart.ParentNode.Remove()

Best regards.

Thank you Alexey for this information but, unfortunately, this code isn’t good because it breaks the Start/End bookmark nodes.

Try to delete successively the bookmarks in the sample attached :
“AtConclusionSVisé”
“AtConclusionANVisé”
“AtConclusionPNVisé”
“AtConclusionMNVisé”

Regards,

Hi
Thanks for your request. I tried to use your code with your firs document. And after removing ChLaboAgr field imgCertificat was not removed. I used the following code:

Dim doc As Document = New Document("newdoc.doc")
Dim book As Bookmark = doc.Range.Bookmarks("ChLaboAgr")
RemoveBookmarkWithContent(book)

Best regards.

Thank’s for your reply.
This method doesn’t works with the attached document.

Could you check it ?

Thank you

Emmanuel

Hi,

I forgot to give you the field name which is filled just before removing the bookmark “ChLaboAgr” :
«Image:ImgCertificat»

Thank you

Emmanuel

Hi
Thanks for your request. I think that you can try to remove bookmarks before perform mail merge. See the following code:

Dim doc As Document = New Document("ModeleAmV2.doc")
Dim book As Bookmark = doc.Range.Bookmarks("ChLaboAgr")
RemoveBookmarkWithContent(book)
Dim names As String() = {"ImgCertificat 455 580"}
Dim values As String() = {"test.jpg"}
doc.MailMerge.Execute(names, values)
doc.Save("out.doc")

Hope this helps.
Best regards.