Inserting text at a bookmark spanning a table cell

Hi all
Our usecase
We are using Aspose for manipulating existing word documents created by MS Word. See the attached document for example. In this example document we want to insert text at the bookmark “AsposeTest” spanning a table cell.
Our findings so far
We are able to insert text at specified bookmarks. This works fine for simple bookmarks. As explained in the aforementioned use case, we need to insert text at a bookmark spanning a table cell which is not the first cell of a row.
The open xml created by word for the table has the following structure:



We tried to insert the text at this bookmark via navigating to the cell of the bookmark start element. Because the bookmark start element is placed into the first cell of the containing row irrespective of the bookmark’s actual containing cell, it is not possible to place text into the second cell of the row.
Does Aspose offer any function to fulfill this requirement?

Cheers
Ivan

Hi
Ivan,

Thanks for your inquiry. First of all, please note that DocumentExplorer is a very useful tool which easily enables us to see the entire document structure. You can find DocumentExplorer in the folder where you installed Aspose.Words e.g. C:\Program Files (x86)\Aspose\Aspose.Words for .NET\Demos\CSharp\DocumentExplorer\bin\DocumentExplorer.exe. Below is the DOM structure of your document as viewed with DocumentExplorer :

You can try something like below to write content in above locations:

Document doc = new Document(@"C:\test\example.docx");
BookmarkStart start = doc.Range.Bookmarks["AsposeTest"].BookmarkStart;

//Move to first cell
Cell cell1 = start.ParentNode.ParentNode as Cell;

// Write some partial text to first cell
Run run1 = new Run(doc);
run1.Text="Text inside first cell";
Paragraph p1 = start.ParentNode as Paragraph;
p1.Runs.Add(run1);

// Move to next cell
Cell cell2 = start.ParentNode.ParentNode.NextSibling as Cell;

// Write some run of text here
Run run2 = new Run(doc);
run2.Text = "Partial text in cell 2";
cell2.Paragraphs[0].Runs.Add(run2);
doc.Save(@"C:\Test\out.doc"); 

I hope, this will help.

Best Regards,

Hi

Thanks for the quick reply. Your proposed solution works fine.

This leads to my next problem.
Assuming I have a row with five cells where a bookmark has been inserted using Word in the third cell of the row, how do I identify the correct cell where my bookmark has been inserted? As in the example document, the Aspose Bookmark Object offers no functionality to figure out column information provided by the openxml

<w:bookmarkStart w:id="0" w:name="AsposeTest" w:colFirst="1" w:colLast="1"/>

As you can see, the position information for the bookmark is part of its Xml Element. I would like to access the w:colFirst and w:colLast attributes. of the Xml Element.

Best Regards
Ivan

Hi,

Thanks for your inquiry. First of all, please note that there is no “column” concept in the Word table. By Microsoft Word design rows in a table in a Microsoft Word document are completely independent. It means each row can have any number of cells. Secondly, you can easily get the first ancestor cell of the bookmark by using the following code snippet:

BookmarkStart start = doc.Range.Bookmarks["AsposeTest"].BookmarkStart;
Cell cell = (Cell)start.GetAncestor(NodeType.Cell);

Moreover, I would suggest you please read the following articles for better understanding of Aspose.Words:
https://docs.aspose.com/words/net/aspose-words-document-object-model/

Please let us know if you need more information, We are always glad to help you.

Best Regards,

Hi

Thanks for your reply.

Your suggested approach solves our problem under the assumption that the bookmark start element is in the correct cell.

But since Word stores all bookmarks start elements of a row in the
first cell (see my last post), the ancestor of the bookmark start
element is the first cell of the row irrespective of the actual cell
where I inserted the bookmark using word.

Example:

I insert a new bookmark spanning the whole cell (as I did in the example
document) in the second cell of the row. Word stores the bookmark start
element into the first cell of the respective row and additionally
stores the position information into the Xml element of the bookmark information (see first post).

<w:bookmarkStart w:id="0" w:name="AsposeTest" w:colFirst="1" w:colLast="1"/>

In my example document, the bookmarkStart.GetAncestor(NodeType.Cell) returns the first cell of the row. Which is correct since the bookmark start element is part of the first cell, but if you open the document using Word, you will see that the bookmark is actually in the second cell of the row. Hence, I have no way to identify the bookmark’s actual position information.

Do you agree?

Cheers
Ivan

Additionally, I created a word document using Aspose with a bookmark in the second cell.
Code:

var builder = new DocumentBuilder();
builder.StartTable();
var cell = builder.InsertCell();
var cell = builder.InsertCell();
var paragraph = cell.FirstChild as Paragraph;
paragraph.AppendChild(new BookmarkStart(builder.Document, "name"));
builder.EndRow();
builder.EndTable();
builder.EndBookmark("name");
return builder.Document;

I attached the resulting open xml files. First one using word to add a bookmark. Second ond using Aspose to add a bookmark.

As you can see, Aspose inserts the bookmark start into the actual cell. On the other hand, word inserts the bookmark start into the first cell of the row.

Cheers
Ivan

Hi,
Thanks for your inquiry. I would suggest you please read the following API link on Bookmarks in Aspose.Words:
https://docs.aspose.com/words/net/working-with-bookmarks/
Moreover, you can insert whole bookmark inside row2 cell2 (i.e. position B2) using MS WORD as well. Just place cursor in that cell and insert a bookmark. I have attached a sample DOCX file for your reference here.
Please let me know if I can be of any further assistance.
Best Regards,

Hi

Thanks for the reply and the docx document.

This would work fine, but it is not enough that the cell contains a bookmark, hence bookmark start and end are in the cell. It is a must for us, that the bookmark exactly has the same structure as in the example document. It is not enough to place a bookmark into the cell, we need to place the bookmark around the cell. The previous post and the example document present an example of a bookmark which contains the cell.

Hence, inserting whole bookmarks is not enough, we need a bookmark which has the bookmark start element in the desired cell and has the bookmark end element outside this cell (see example).

Aspose and Word do not behave the same when it comes the bookmark spanning a cell. Word inserts the bookmark start into the first cell providing position information, Aspose inserts the bookmark start into the correct cell, but does not allow that the bookmark end is at the same place as it it when using word.

I think that the position information for the bookmark start element (if it is inserted as in the example document) is missing. Or do I miss something?

Cheers
Ivan

Hi Ivan,
Thanks for your request. By Aspose.Words design, bookmark’s nodes (BookmarkStart and BookmarksEnd) are inline. This mean that BookmarkStart and BookmarkEnd can be children of paragraphs only. This is described in the documentation here:
https://reference.aspose.com/words/net/aspose.words/bookmarkstart/
We will consider improving table bookmarks in one of future versions.
Best regards,

Hi

Thanks for the reply. Improving table bookmarks would be great:-)

Cheers
Ivan

The issues you have found earlier (filed as WORDSNET-721) have been fixed in this Aspose.Words for .NET 18.9 update and this Aspose.Words for Java 18.9 update.

@iappert,
It is to inform you that we added support of bookmark import on block, cell, and row levels in Aspose.Words 18.9.
In previous versions of Aspose.Words, bookmarks were supported only at the inline-level, that is inside Paragraph node.
Now, bookmark position is preserved in document node structure on import and export of DOCX, DOC, WML documents.