Removing bookmark text changes style

Good day -

My team is experiencing an issue in Aspose.Words when replacing bookmark contents.

I have attached a document with a very simple example. In it, you will see something like the following:

[Benefits]
Pricing
Pricing above should be orange.

where [Benefits] is actually the word Benefits, plus a line break, contained within a bookmark called BenefitsSection

What we often do is delete a chunk of text (including images, etc.) in a document by removing the bookmark and its contents; in this case:
(this is ColdFusion)

<cfset bookmark = templateDoc.Range.getBookmarks().get(“BenefitsSection”)>
<cfset bookmark.setText("")>
<cfset bookmark.remove()>

However, when we do that, the style of the following text - Pricing - gets removed. It turns into the same style as the text following it (“Pricing above should be orange”).

What we need to do is remove the contents of the bookmark entirely, and retain the style of the following text. In this case, we can “solve” the issue by including an extra line break before Pricing; unfortunately we can’t do that in some of our documents due to style guidelines.

Is there something we’re doing wrong that causes the style to change?

Thank you for your time.

Hi Chris,

Thanks for your query. I have managed to reproduce the same issue at my side. I have logged this issue as WORDSNET-7030 in our issue tracking system. I have linked this forum thread to the same issue and you will be notified via this forum thread once this issue is resolved.

We apologize for your inconvenience.

Hi Chris,

Thanks for your patience. I have received response from our development team about this issue and like to share with you that this is not a bug. Please note that Aspose.Words mimics the same behavior as MS Word do.

Please see the attached screenshot, there is Paragraph at the end of the bookmark “BenefitsSection” (inside bookmark). After removing this paragraph in MS Word you will get the same result like using Aspose.Words.

In this case, you can use following code snippet for the solution of this issue instead of using Bookmark.Text property.

Document doc = new Document(MyDir + "testaspose.docx");
Aspose.Words.Bookmark bm = doc.Range.Bookmarks["BenefitsSection"];
Node currentNode = bm.BookmarkStart;
while (currentNode != bm.BookmarkEnd)
{
    currentNode = currentNode.NextPreOrder(doc);
    if (currentNode.NodeType == NodeType.Run)
        ((Run)currentNode).Text = "";
}
// bm.Text = "";
doc.Save(MyDir + "AsposeOut.docx");

Please let us know if you have any more queries.

Hello and thank you for the reply.

We will certainly use the solution you presented to make our application work.

I was able to create the same scenario you produced above; however I would like to point out that the behavior is not quite exactly the same as Word.

In your screenshot scenario, the following paragraph style changes if the user deletes only the paragraph marker.

If, on the other hand, the user highlights and deletes the entire bookmark contents - up to and including the paragraph marker - the behavior is not exhibited. This was my expectation when choosing to delete content of the bookmark. In the attached screenshot, I highlighted the entire paragraph (box #1) as shown and hit the “delete” key. Box #2 was the result; the paragraph retained its style.

Likewise, if put my mouse by the “B” - the first letter in the bookmark - and hit delete, delete, delete, etc., until I deleted the paragraph marker (box #3), the paragraph still retained the proper style. It sounds like the above code intends to replicate this behavior and we are willing to try it. I assume that this will remove the paragraph marker as well. As I mentioned in the initial post, we do need to remove the entire line including the paragraph.

In effect, I’m pointing out that scenario #1 on my attached screenshot is how I’d expect the delete to work, if Aspose were trying to emulate MS Word behavior down to a very fine detail. But it is a very minor thing.

Thanks again.

Hello again -

We plugged in the above code on the simple example, and it does not remove the paragraph mark that is inside the bookmark.

When we open the resulting document in Word and delete the paragraph mark that is left, it deletes correctly and the following paragraph retains its style. However, there does not seem to be a way to do this programmatically by going through the Run nodes, unless you have a way of doing that reliably. So we are back to the original scenario, I think.

I have one more question on your example - there is a line such as currentNode.Text="". However the “Text” property is not in the javadoc for the Node class. I see this quite frequently in examples and wonder if this is an undocumented feature, because there is no corresponding setText() method. I am careful to ask my team to try to use the javadoc whenever possible so we don’t use an unintended feature.

Thank you.

Hi Chris,

Thanks for your inquiry. Please accept my apologies for your inconvenience. I shared the .NET code, please use the following Java code snippet for your requirement. If you want to delete paragraph mark that is inside the bookmark, please use Paragraph.remove method to remove paragraph node.

https://reference.aspose.com/words/java/com.aspose.words/Run

Document doc = new Document(MYDir + "testaspose.docx");
Bookmark bm = doc.getRange().getBookmarks().get("BenefitsSection");
Node currentNode = bm.getBookmarkStart();
while (currentNode != bm.getBookmarkEnd())
{
    currentNode = currentNode.nextPreOrder(doc);
    if (currentNode.getNodeType() == NodeType.RUN)
        ((Run)currentNode).setText("");
}
if (bm.getBookmarkStart().getParentNode().getNodeType() == NodeType.PARAGRAPH)
    if (bm.getBookmarkStart().getParentNode().getText().trim().equals(""))
        bm.getBookmarkStart().getParentNode().remove();
doc.save(MYDir + "AsposeOut.docx");

Hello again. Thank you for the continued suggestion.

While the above code works for the particular case in question, when I expand the bookmark to include paragraph markers in positions other than the last position, they do not get removed. Please see the attached screenshot showing the before/after.

As you can see, there are six paragraph markers inside the bookmark, including the last marker. After the Aspose is run, there are five. I presume we are removing the last node but not the others.

For reference, here is the code we used. I converted it to ColdFusion but it appears to be accurate:

*<cfset bookmark = templateDoc.Range.getBookmarks().get(“BenefitsSection”)>
<!— <cfset bookmark.setText("")> —>

<cfif currentNode.nodeTypeToString(currentNode.getNodeType()) eq “Run”>
<cfset currentNode.setText("")>

<cfif bookmark.getBookmarkStart().getParentNode().getNodeType() eq NodeType.PARAGRAPH and
bookmark.getBookmarkStart().getParentNode().getText().trim() eq “”>
<cfset bookmark.getBookmarkStart().getParentNode().remove()>

<cfset bookmark.remove()>*

I wonder if there is another NodeType (besides “Run”) that should be removed as we traverse through the bookmark’s nodes?

Thank you.

Hi Chris,

Thanks for your inquiry. First of all, please note that Aspose.Words is quite different from the Microsoft Word’s Object Model in that it represents the document as a tree of objects more like an XML DOM tree. If you worked with any XML DOM library you will find it is easy to understand and work with Aspose.Words. When you load a Word document into Aspose.Words, it builds its DOM and all document elements and formatting are simply loaded into memory. Please read the following articles for more information on DOM:
https://docs.aspose.com/words/net/aspose-words-document-object-model/
https://docs.aspose.com/words/net/logical-levels-of-nodes-in-a-document/

Please use following code snippet for your requirement and check the attached image for DOM detail.

Document doc = new Document(MyDir + "in.docx");
Aspose.Words.Bookmark bm = doc.Range.Bookmarks["BenefitsSection"];
Node currentNode = bm.BookmarkStart;
while (currentNode != bm.BookmarkEnd)
{
    currentNode = currentNode.NextPreOrder(doc);
    if (currentNode.NodeType == NodeType.Run)
        ((Run)currentNode).Text = "";
}
ArrayList nodes = new ArrayList();
currentNode = bm.BookmarkStart;
while (currentNode != bm.BookmarkEnd)
{
    currentNode = currentNode.NextPreOrder(doc);
    if (currentNode.NodeType == NodeType.Paragraph)
        if (((Paragraph)currentNode).GetText().Trim() == "" && ((Paragraph)currentNode).ParentNode != null)
            nodes.Add(currentNode);
}
foreach (Node node in nodes)
{
    node.Remove();
}
doc.Save(MyDir + "AsposeOut.docx");

The issues you have found earlier (filed as WORDSNET-7030) have been fixed in this .NET update and this Java update.

This message was posted using Notification2Forum from Downloads module by aspose.notifier.

Hello,

I am witnessing the same behavior when deleting the contents of the entire bookmark, up to and including the paragraph marker, using bookmark.setText("").

Is this the behavior that was fixed in the update, or was it a different behavior? Or was that just placed to close out the thread? I’m still unable to delete the last remaining node, given the code above.

Thank you.

Hi Chris,

Thanks for your inquiry. Please note that Aspose.Words mimics the same behavior as MS Word do. The issue discussed in this thread is not a bug. Please check my reply at following forum link.
https://forum.aspose.com/t/51040

Could you please attach your input Word document here for testing? I will investigate the issue on my side and provide you more information.

Hello -

I agree that you already noted that the Aspose behavior is the same as MSWord. But the thread was auto-updated to say an issue was fixed. I was just questioning what was fixed, if there was not an issue to begin with.

My doc is attached to the first post of the thread. While Aspose does mimic the behavior of MSWord in certain cases, it doesn’t in others. Post 419786 explains how MSWord works when you delete an entire string of text - including a paragraph break - at once, vs. how Aspose works when doing the same action. I tried to be very detailed and provided a screenshot to accompany the explanation.

Again, I accept it if you say Aspose is behaving correctly. But I am questioning the auto-post that says the behavior has changed with the latest Aspose release, because the behavior seems the same.

Thank you.

Hi Chris,

Thanks for your inquiry and sorry for this confusion. Please note that, as mentioned here, the fix of your issue was not implemented. Actually, this post here was sent by an automated system. We will be sure to improve our notification system to avoid such confusions in the future.

Best Regards,

i want to insert table inside row which will be dynamic.Please let me know how to do it.
and it will be boomarked with bullet.

I have multiple row in which every row has multiple dynamic table with data and row is bookmarked also how I will do program regard java please let me know.

@kritisuman,

Thanks for your inquiry. Please refer to the following article about creating nested tables. Please check the code examples in following article. Hope this helps you.
Inserting a Table using DocumentBuilder