Free Support Forum - aspose.com

Removed Bookmark appears twice in Document#Range#Bookmarks

Dear Aspose team!

A strange problem occured after removing bookmarks from a document.

The following steps are executed:

1. looking up particular bookmarks (not all!) from Document#Range#Bookmarks, filtered by name patterns

2. storing the found bookmarks in a separate list

3. iterating over the list:

a) filling the table which is nested in each bookmark

b) removing the bookmark by calling Bookmark#Remove() immediately after filling it

4. getting the remaining bookmarks from the document by Document#Range#Bookmarks again

5. starting a new iteration to remove each remaining bookmark with its content

In 4, I get a BookmarkCollection that contains all bookmarks that should have been removed in 3b) even twice!!!

5. raises an exception because the bookmark is already removed (start and end have no parent):

System.InvalidOperationException: Cannot find bookmark 'XY' in the document.

At first, I thought that there could be a concurrent modification problem: iterating over the BookmarkCollection in Range and removing the bookmarks during the iteration. But as you can see in 2., they are stored in a separate list to make them ready for removal.

Do you know what could have happened?

Please let me know if you require source code or the document. The sources are a little more complex because we use a layer that is abstracting from Aspose.Words (by adapter classes).

Thanks a lot for your help,

cheers,

Stephan

Additional information:

I am using Aspose.Words version 8.1.

Another information:

I added an event handler to Document.NodeInserted to observe the adding of Nodes; but there was no BookmarkStart or BookmarkEnd added...

Hi

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thanks for your inquiry. Could you please provide me the document and simple code, or create a simple application, which will allow me to reproduce the problem on my side? I will check the issue and provide you more information.

Best regards,

Hi Andrey!

Sure, please find attached the sample document table_tmp.docx.

In source_code.docx, you'll find some of the code (simplyfied) that is used.

It contains some annotations that hopefully make it easier to understand the sources.

Please let me know if anything is not clear of if there is some more information to be provided.

Thank you very much for your great support,

cheers,

Stephan

Hi Stephan,

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Thank you for additional information. There is no problem with removing bookmark. I suppose, in your code you clone the table or the first row of table, which contains bookmark start. Here is the simplified code, which demonstrates the issue:

string bkName = "C5601Tab000000000000328";

// Open document.

Document doc = new Document(@"Test001\table_tmp.docx");

// Get table. The first cell of the teble contains BookmarkStart node.

Table table = (Table)doc.GetChild(NodeType.Table, 0, true);

// Copy the row with bookmark start few times.

for (int i = 0; i < 10; i++ )

table.Rows.Add(table.FirstRow.Clone(true));

// Remove the bookmark

doc.Range.Bookmarks[bkName].Remove();

// Print bookmarks. We will see that there are 10 bookmarks with the same name.

// The same number as number of rows we added.

foreach (Bookmark bookmark in doc.Range.Bookmarks)

Console.WriteLine(bookmark.Name);

So the solution of the problem is pretty simple, you should just remove bookmarks nodes from the cloned row, like shown below:

string bkName = "C5601Tab000000000000328";

// Open document.

Document doc = new Document(@"Test001\table_tmp.docx");

// Get table. The first cell of the teble contains BookmarkStart node.

Table table = (Table)doc.GetChild(NodeType.Table, 0, true);

// Copy the row with bookmark start few times.

for (int i = 0; i < 10; i++)

{

Row row = (Row)table.FirstRow.Clone(true);

row.GetChildNodes(NodeType.BookmarkStart, true).Clear();

row.GetChildNodes(NodeType.BookmarkEnd, true).Clear();

table.Rows.Add(row);

}

// Remove the bookmark

doc.Range.Bookmarks[bkName].Remove();

// Print bookmarks. We will see that there are 10 bookmarks with the same name.

// The same number as number of rows we added.

foreach (Bookmark bookmark in doc.Range.Bookmarks)

Console.WriteLine(bookmark.Name);

Also, duplicated and corrupted bookmarks will be removed automatically before saving the document.

Hope this helps.

Best regards.

Excellent, excellent, excellent, great!!!

That was exactly my problem!!!!

Thank you so much for your fast and perfect support!

Cheers,

Stephan