Spire.Doc is a professional Word .NET library specifically designed for developers to create, read, write, convert and print Word document files. Get free and professional technical support for Spire.Doc for .NET, Java, Android, C++, Python.

Wed Mar 18, 2026 8:44 am

Thank you very much for your detailed answer and the proposed workaround.

One question to your sample code.
Code: Select all
Paragraph para = (Paragraph) bk.getBookmarkStart().getOwner();
Section sec = (Section) para.getOwner().getOwner();


Will these two lines always work, i.e., will the 1st line always return a Paragraph object and will the 2nd line always return a Section object? Or do I have to check the returned instance type?

Saying that, wouldn't it be more precise to use the following code?
Code: Select all
Paragraph para = bk.getBookmarkStart().getOwnerParagraph();
bookmarksNavigator.moveToBookmark(bk.getName());
bookmarksNavigator.deleteBookmarkContent(true);
if (para.getText().isEmpty()) {
    para.getOwner().getChildObjects().remove(para);
}


Or should I better use this alternative code?
Code: Select all
Paragraph para = bk.getBookmarkStart().getOwnerParagraph();
bookmarksNavigator.moveToBookmark(bk.getName());
bookmarksNavigator.deleteBookmarkContent(true);
if (para.getText().isEmpty()) {
    Section sec = para.getParentSection();
    sec.getParagraphs().remove(para);
}


As you can see, I'm looking for a general purpose code that works for any document structure.

Kind regards,
Marcus
Last edited by mgattinger on Wed Mar 18, 2026 9:49 am, edited 1 time in total.

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Wed Mar 18, 2026 9:58 am

Hello,

Thank you for your feedback,
Yes, your current approachs are more general, previously only based the provided document. The "para.getOwner().getOwner()" may not always return a Section, if the bookmark is in a table, "para.getOwner().getOwner()" returns Table_row, the structure is similar to the screenshot below.
str1.png


Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1534
Joined: Wed Apr 25, 2018 3:20 am

Wed Mar 18, 2026 10:07 am

Hi Lisa!

Thanks again for your answer. I'm not sure about the difference between a Section and a Body. Can you explain me the difference, please?

Furthermore I found another issue during my testing with removing bookmark content.

The following code will produce a NullPointerException somewhere deep in your library:
Code: Select all
Document document = new Document("Test3.docx");
Bookmark bookmark = document.getBookmarks().findByName("Chapter");
Paragraph paragraph = bookmark.getBookmarkStart().getOwnerParagraph();
BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(document);
bookmarksNavigator.moveToBookmark(bookmark.getName());
bookmarksNavigator.deleteBookmarkContent(true);
if (paragraph.getText().isEmpty()) {
    Section section = paragraph.getParentSection();
    section.getParagraphs().remove(paragraph);
}
document.updateTableOfContents();
document.saveToFile("Test3.generated.docx");


And this is the exception that occurs when calling
document.updateTableOfContents()
:
Code: Select all
java.lang.NullPointerException: Cannot invoke "com.spire.doc.DocumentObject.spr⌾⅝()" because the return value of "com.spire.doc.documents.Paragraph.spr┅⅝()" is null
   at com.spire.doc.documents.Paragraph.spr┴┶—(Unknown Source)
   at com.spire.doc.packages.sprnvz.spr≇™—(Unknown Source)
   at com.spire.doc.packages.sprfzaa.spr≃‣—(Unknown Source)
   at com.spire.doc.packages.sprfzaa.spr┃¬(Unknown Source)
   at com.spire.doc.packages.sprlaz.spr╄⅚(Unknown Source)
   at com.spire.doc.Document.spr↡‰—(Unknown Source)
   at com.spire.doc.Document.updatePageLayout(Unknown Source)
   at com.spire.doc.Document.spr︻‱—(Unknown Source)
   at com.spire.doc.Document.spr┛‰—(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr◑⅞(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr┩⅞(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr⌫⅞(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr≌⅟(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr┋⅟(Unknown Source)
   at com.spire.doc.packages.sprsjz.spr㈭⃟⅞(Unknown Source)
   at com.spire.doc.Document.spr╻‰—(Unknown Source)
   at com.spire.doc.Document.spr⌮‰—(Unknown Source)
   at com.spire.doc.Document.spr┢‰—(Unknown Source)
   at com.spire.doc.Document.spr█‰—(Unknown Source)
   at com.spire.doc.Document.updateTableOfContents(Unknown Source)


Regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Thu Mar 19, 2026 6:04 am

Hello,

Thank you for your feedback,
In the Word document processing structure, "Body" refers to all the body content of the Word document, while "Section" refers to the document format configuration. In order to manipulate the content of different Sections, it needs to first obtain the corresponding sub elements under the Body through a specific Section. Hope it can help you.
Additionally, regarding the "Test3.docx", it is because the bookmark is in the table cell. But in "section.getParagraphs().remove(paragraph);", the "section.getParagraphs()" returns the paragraphs under Section/Body, not the paragraphs from the Table_cell, the forced deletion has caused some structural abnormalities. You can print out the type information with the following code and check.
Code: Select all
        Document document = new Document("Test3.docx");
        Bookmark bookmark = document.getBookmarks().findByName("Chapter");
        Paragraph paragraph = bookmark.getBookmarkStart().getOwnerParagraph();
        System.out.println("Current Type:"+paragraph.getOwner().getDocumentObjectType().toString());
        BookmarksNavigator bookmarksNavigator = new BookmarksNavigator(document);
        bookmarksNavigator.moveToBookmark(bookmark.getName());
        bookmarksNavigator.deleteBookmarkContent(true);
        if (paragraph.getText().isEmpty()) {

            Section section = paragraph.getParentSection();
            for (int i=0;i<section.getBody().getChildObjects().getCount();i++)
            {
                System.out.println("Type:"+section.getBody().getChildObjects().get(i).getDocumentObjectType().toString());

            }
            System.out.println("Paragraphs no:"+  section.getParagraphs().getCount());
            section.getParagraphs().remove(paragraph);
        }
        document.updateTableOfContents();
        document.saveToFile("Test3.generated.docx");

Thus, if only deleting the paragraph where the bookmark is located, please use:
Code: Select all
if (para.getText().isEmpty()) {
    para.getOwner().getChildObjects().remove(para);
}


Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1534
Joined: Wed Apr 25, 2018 3:20 am

Mon Mar 23, 2026 9:45 am

Hi Lisa!

Thank you for the information. That helped me to understand the structure of the document.

However, I don't understand why the method call "section.getParagraphs().remove(paragraph)" breaks the document if the paragraph to remove is not found within the collection returned by "section.getParagraphs()".

Consider the following test code:
Code: Select all
Document document = new Document("Test3.docx");
Bookmark bookmark = document.getBookmarks().findByName("Chapter");
Paragraph paragraph = bookmark.getBookmarkStart().getOwnerParagraph();
Section section = paragraph.getParentSection();
for (int i = 0; i < section.getParagraphs().getCount(); i++) {
    Paragraph p = section.getParagraphs().get(i);
    if (p == paragraph) {
        System.out.println("Section contains bookmark paragraph.");
    }
}
section.getParagraphs().remove(paragraph);
document.updateTableOfContents();


You won't see the text "Section contains bookmark paragraph", so I would expect the line "section.getParagraphs().remove(paragraph)" does not have any effect. However, it has and the call to "document.updateTableOfContents()" causes a NullPointerException somewhere in your code because the document structure seems to be broken. Hence, I assume you have to fix how the method "remove(paragraph)" work to make it more fail-safe by either ignore the request to remove the paragraph or throw an exception that clearly states that the paragraph to remove has not been found.

Regards,
Marcus

mgattinger
 
Posts: 65
Joined: Fri May 21, 2021 9:03 am

Tue Mar 24, 2026 2:17 am

Hello,

Thank you for your feedback,
Yes, in this scenario, there should be relevant prompts for "section.getParagraphs().remove(paragraph)". Our Dev team colleagues are investigating the underlying logic and optimizing it now, this task is recorded using SPIREDOC-11870. Once there is any progress, we will provide feedback to you. Thank you for your understanding.

Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1534
Joined: Wed Apr 25, 2018 3:20 am

Wed Apr 15, 2026 6:19 am

Hello,

Regarding the issues mentioned previously, here is the current progress:
1.SPIREDOC-11860: Our Dev team has modified the underlying code, which is currently under testing. We will provide you with the corresponding hotfix version as soon as the tests pass.
2.Regarding the parameter "deleteBookmarkContent(true):", When set to "true", the style of the original bookmark content should be retained. Upon further confirmation, after using this setting, please use "bookmarkNavigator.insertText("Add new");" to insert the new content.
3.SPIREDOC-11870: Our Dev team has confirmed that the underlying remove method currently lacks this part internal judgments. Implementing this would require modifying a significant amount of code, which could potentially introduce unexpected impacts. Therefore, we will not be making this adjustment at the moment. Currently, we can only avoid such issues through external judgment.
Code: Select all
        Document document = new Document("Test3.docx");
        Bookmark bookmark = document.getBookmarks().findByName("Chapter");
        Paragraph paragraph = bookmark.getBookmarkStart().getOwnerParagraph();
        Section section = paragraph.getParentSection();

        if (section.getParagraphs().contains(paragraph)) {
            System.out.println("Section contains bookmark paragraph.");
            section.getParagraphs().remove(paragraph);
        }
        document.updateTableOfContents();


Sincerely,
Lisa
E-iceblue support team
User avatar

Lisa.Li
 
Posts: 1534
Joined: Wed Apr 25, 2018 3:20 am

Return to Spire.Doc

cron