Editing bookmark on header or footer of word Doccument

(ASPOSE WORDS)
API: bookmark.setText(“abc”)
Error: Illegal State Exception
StackTrace is given belove
We have observed in nested bookmark if parent bookmark is updated with bookmark text we could not update child node, this case arises when we add bookmark programmatically in prefix to another bookmark.
Ex: “bookmark2””bookmark1”
(Note:Here we added “bookmark1” first and took cursor to first index and added another bookmark “bookmark2”)
When we traverse it programmatically using bookmark collection of aspose we are getting both bookmarks and if we update text of bookmark1 then we cannot update text of bookmark2 it gives bookmark doesn’t exist error.
Can we get to know in which data structure this nested bookmarks saved?
How can we traverse and update bookmarktext of all bookmarks?
StackTrace:
java.lang.IllegalStateException: Cannot find bookmark ‘CONTRACT_EFFECTIVE_DATE64829’ in the document.
at com.aspose.words.zzZJ.zzV(Unknown Source)
at com.aspose.words.Bookmark.getBookmarkEnd(Unknown Source)
at com.aspose.words.Bookmark.setText(Unknown Source)

Can you help me on how can i update text of all bookmarks added

@Karthik_M

Thanks for your inquiry. To ensure a timely and accurate response, please attach the following resources here for testing:

  • Your input Word document.
  • Please create a simple Java application ( source code without compilation errors ) that helps us to reproduce your problem on our end and attach it here for testing.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

Aspose Word.zip (12.0 KB)
Hi @tahir.manzoor ,
Thank you for Quick Responce ,
I have uploaded java code and doccument,

@Karthik_M

Thanks for sharing the detail. We have tested the scenario using the latest version of Aspose.Words for Java 19.1 and have not found the shared issue. Please use Aspose.Words for Java 19.1. We have attached the output document with this post for you kind reference.

output document.zip (11.2 KB)

If you still face problem, please manually create your expected Word document using Microsoft Word, ZIP and attach it here for our reference. We will investigate how you want your final Word output be generated like. We will then provide you more information on this along with code.

@tahir.manzoorexpected_output_document.zip (26.7 KB)

Thank you for your Response

We have added total of 12 bookmarks so our expected behavior in footer is little different.
We have added bookmark on header in succeeding order where as in footer we added bookmarks in preceding order (programatically and as per our observation bookmarks in footer are being added as nested bookmarks and we need all the bookmark text to be replaced and shown on the document) .
I have attached expected output on this response.

@Karthik_M

Thanks for sharing the detail. Please check the attached DOM image of your document.

Your document contains the nested bookmarks. In your case, you need to iterate over paragraph’s nodes and remove the BookmarkStart and BookmarkEnd nodes between bookmark Contract_Value43823. Hope this helps you.

@tahir.manzoor
Thanks for sharing details,
We can iterate over paragraph’s nodes and remove the BookmarkStart and BookmarkEnd nodes between bookmark Contract_Value43823,
but we are expecting a behavior where we retain all the bookmarks in the preceding order(not in nested structure i.e, we need all the inner bookmark to be placed preceding its parent as a plain structure),
Ex:
[Bookmark Start-61100 Bookmark End-61100]
[Bookmark Start-51679 Bookmark End-51679]
[Bookmark Start-59824 Bookmark End-59824]
[Bookmark Start-67970 Bookmark End-67970]
[Bookmark Start-43823 Bookmark End-43823]

Can you help me with how we can traverse and add bookmark in a flat structure as shown in the example mentioned above

@Karthik_M

Thanks for your inquiry. In your shared expected output document, the footer contains only one bookmark.

Please manually create your expected Word document using Microsoft Word and attach it here for our reference. We will investigate how you want your final Word output be generated like. We will then provide you more information on this along with code.

@tahir.manzoor
Thank you for quick response
I have atached expected output , code snippet and description on zip file , I think this will help you.
expected_output_document.zip (26.7 KB)

@Karthik_M

Thanks for sharing the detail. In case of nested bookmark, you can use following code example to get the desired output. This code example does not set the bookmark’s text. Please set it according to your requirement.

Document doc = new Document(MyDir + "Disclosure.docx");

HeaderFooter headerFooter = doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY);

if(headerFooter.getRange().getBookmarks().getCount() > 0)
{
   Bookmark bm = headerFooter.getRange().getBookmarks().get(0);
    Boolean nestedbm = false;
    Node node = bm.getBookmarkStart();
    while (node != bm.getBookmarkEnd())
    {
        node = node.nextPreOrder(doc);
        if(node == null)
            break;
        if(node.getNodeType() == NodeType.BOOKMARK_START || node.getNodeType() == NodeType.BOOKMARK_END)
        {
            if(!node.equals(bm.getBookmarkEnd()))
            {
                nestedbm = true;
                break;
            }
        }
    }

    System.out.println("Nested bookmark existed in the range " + nestedbm);
    if(nestedbm)
    {
        node = bm.getBookmarkStart();
        while (node != bm.getBookmarkEnd())
        {
            node = node.nextPreOrder(doc);
            if(node == null)
                break;
            if(node.getNodeType() == NodeType.BOOKMARK_START || node.getNodeType() == NodeType.BOOKMARK_END)
            {
                Node bookmark = node;
                node = node.nextPreOrder(doc);
                if(bookmark.equals(bm.getBookmarkStart()) || bookmark.equals(bm.getBookmarkEnd()))
                    continue;

                bookmark.remove();
            }

        }
    }
}
doc.save(MyDir + "19.1.docx");

@tahir.manzoor
Thank you for your quick response,
I have tried this and we cannot set bookmark text ,
In our use case I need to retain bookmark and it’s value for further updates, Is there any way where I can retain my bookmark (in flat structure of desired output i.e, not in nested form).

@Karthik_M

Thanks for your inquiry.

The expected output document you shared in this forum thread has one bookmark in the footer of document. Please check it again. If you want to retain all bookmarks, the code example shared by me does not work.

If you want to keep all bookmarks in the document, you need to iterate over all bookmarks in the range, move the cursor to the desired location and insert the bookmark with same name.

@tahir.manzoor

Thank you for consideration
i have attached output document (created manually, you can get an idea by reffering the document)
expected_output_document.zip (14.9 KB)

@Karthik_M

Thanks for sharing the detail. We are investigating this issue and will get back to you soon.

@Karthik_M

Thanks for your patience. Please use the following code example to get the desired output. Hope this helps you.

Document doc = new Document(MyDir + "Disclosure.docx");
DocumentBuilder documentBuilder = new DocumentBuilder(doc);

// Get the footer
HeaderFooter headerFooter = doc.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY);
//Clone the footer
HeaderFooter headerFooterClone = (HeaderFooter) headerFooter.deepClone(true);
//remove the text of bookmark. The clone nodes have the text
for(Bookmark bookmark : headerFooter.getRange().getBookmarks())
{
    bookmark.setText("");
}
int bookmarkcount = headerFooterClone.getRange().getBookmarks().getCount();
if(bookmarkcount > 0)
{
    //Iterate over bookmarks and recreate the bookmarks and their text
    for(int bm = 0; bm < bookmarkcount; bm++)
    {
        Bookmark bookmark =  headerFooterClone.getRange().getBookmarks().get(bm);
        documentBuilder.moveToBookmark(bookmark.getName());
        documentBuilder.startBookmark(bookmark.getName());
        documentBuilder.write("Text" + bm);
        documentBuilder.endBookmark(bookmark.getName());
    }
}
doc.save(MyDir + "19.1.docx");

@tahir.manzoor
Thank you for your help We were actually talking about footer Text to be Replaced
I tried your code snippet for Footer but it was not working

Can you help regarding the same?

@Karthik_M

Thanks for your inquiry. In case, you are using older version of Aspose.Words, we suggest you please use the latest version of Aspose.Words for Java 19.1. The shared code example generates the expected output document that you shared. The code example is for footer’s text.

If you still face problem, please ZIP and attach the problematic output document here for further investigation.

@tahir.manzoor
Thanks for your suggestions,
We are already using Aspose 19.1, Its Removing outer bookmarks text and creating another bookmark,
But in our case, we have many bookmarks in preceding order
I have attached Smple document please check once.

public static void main(String[] args) throws Exception {

	String MyDir = "C:\\Users\\karthik.m\\Downloads\\";
	Document doc = new Document(MyDir + "9947.2.docx");
	DocumentBuilder documentBuilder = new DocumentBuilder(doc);

	// Get the footer
	HeaderFooter headerFooter = doc.getFirstSection().getHeadersFooters()
			.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY);
	// Clone the footer
	HeaderFooter headerFooterClone = (HeaderFooter) headerFooter.deepClone(true);
	// remove the text of bookmark. The clone nodes have the text
	for (Bookmark bookmark : headerFooter.getRange().getBookmarks()) {

		bookmark.setText("");
	}
	int bookmarkcount = headerFooterClone.getRange().getBookmarks().getCount();

	if (bookmarkcount > 0) {
		// Iterate over bookmarks and recreate the bookmarks and their text
		System.out.println("*************************Bookmark Before Change********************************");
		for (int bmBeforChange = 0; bmBeforChange < bookmarkcount; bmBeforChange++) {
			Bookmark bookmark = headerFooterClone.getRange().getBookmarks().get(bmBeforChange);
			System.out.println("BookMarkName: " + bookmark.getName());

			System.out.println("BookMarkText: " + bookmark.getText());
		}

		System.out.println("*************************Bookmark After Change********************************");
	
		for (int bm = bookmarkcount - 1; bm >= 0; bm--) {

			Bookmark bookmark = headerFooterClone.getRange().getBookmarks().get(bm);
			documentBuilder.moveToBookmark(bookmark.getName());
			System.out.println("BookMarkName: " + bookmark.getName());
			System.out.println("BookMarkText: " + bookmark.getText());
			documentBuilder.startBookmark(bookmark.getName());
			String bmName = bookmark.getName();
			//documentBuilder.write(bmName);
			documentBuilder.write("TEXT"+bm);
			System.out.println("newBookmarkText: " + "TEXT" + bm);
			documentBuilder.endBookmark(bookmark.getName());
		}
	}
	doc.save(MyDir + "9947.2.docx");
}

expected_output_document.zip (12.0 KB)

@Karthik_M

Thanks for your inquiry. The bookmark is a “facade” object that encapsulates two nodes BookmarkStart and BookmarkEnd in a document tree and allows to work with a bookmark as a single object. The Run nodes between these nodes contain the text of bookmark.

In your document, the content are bookmarked incorrectly. However, you can generate the desired output using Aspose.Words. We suggest you following solution.

  1. Get bookmark for the desired range.
  2. Clone it to get the bookmarks’ names and text.
  3. Delete the nodes in the range.
  4. Insert the new BookmarkStart and BookmarkEnd nodes and text according to your requirement.