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.

Tue Aug 26, 2014 2:56 pm

Hello,

I have a requirement to get the current text that is within a bookmark before I replace it. I have tried several different methods without success. The closest I came was this

Code: Select all
   ...
   navigator.MoveToBookmark(bookmarkName);
   var body = navigator.GetBookmarkContent();
   Paragraph p = body.BodyItems.FirstItem as Paragraph;
   string bookmarkContext = p.Text;
   ...


But this gets me the whole paragraph text in which the bookmark resides. Meaning we have a paragraph that shows:

Patient Name: [Patient_Name_Bookmark]

And p.Text gets me: "Patient Name: Patient_Name_Bookmark"

Where I only want the text "Patient_Name_Bookmark"

I also experimented with using Bookmark.BookmarkStart and Bookmark.BookmarkEnd, but I'm not sure how to get the text between the two.

It seems like this should be simple, but I'm just not able to get what I need. Honestly, I would have expected something like Bookmark.Text much like Paragraph.Text.

bobradu
 
Posts: 9
Joined: Wed Aug 20, 2014 7:06 pm

Tue Aug 26, 2014 10:26 pm

I managed to get what I needed after a lot of trial and error (and spying the object tree in debug).

This is what I came up with to get the text within a bookmark. Please let me know if you have a better or more efficient way.

Code: Select all
        private static string GetBookmarkContextText(Bookmark bookmark)
        {
            //get the paragraph this bookmark belongs to
            Paragraph p1 = bookmark.BookmarkStart.OwnerParagraph;

            //loop though each child object, looking for the start of the bookmark with the same name, then get the next item (which is in the content) and return that text
            return
                p1.ChildObjects.Cast<DocumentObject>()
                    .Where(child => child is BookmarkStart && ((BookmarkStart) child).Name == bookmark.Name)
                    .Select(child => child.NextSibling)
                    .Where(bookmarkContent => bookmarkContent != null)
                    .Select(bookmarkContent => ((TextRange) bookmarkContent).Text)
                    .FirstOrDefault();
        }

bobradu
 
Posts: 9
Joined: Wed Aug 20, 2014 7:06 pm

Wed Aug 27, 2014 10:25 am

Hello,

Thanks for your inquriy.
The way you used only works fine for the solution that there is only one bookmark in a paragraph, if the bookmark embeds a bookmark or more, the method won't work.
If your documents only include one bookmark, you can use the method you provided, otherwise, please try the following method.
Code: Select all
Document doc = new Document();
doc.LoadFromFile(@"..\..\test.docx");
BookmarksNavigator bookmarkNavigator = new BookmarksNavigator(doc);
bookmarkNavigator.MoveToBookmark("name2");
TextBodyPart part = bookmarkNavigator.GetBookmarkContent();
string text = "";
foreach (var items in part.BodyItems)
            {
                if (items is Paragraph)
                {
                    foreach (var item in (items as Paragraph).ChildObjects)
                    {
                        if (item is TextRange)
                        {
                            text += (item as TextRange).Text;
                        }

                    }
                }

            }

If there are any questions, welcome to get it back to us.
Sincerely,
Gary
E-iceblue support team
Last edited by Gary.zhang on Thu Aug 28, 2014 6:58 am, edited 1 time in total.
User avatar

Gary.zhang
 
Posts: 1380
Joined: Thu Apr 04, 2013 1:30 am

Wed Aug 27, 2014 5:34 pm

Well, the document will contain many bookmarks, but we first try to get the value by bookmark name, then if that fails, we will get it by text in that method, so it generally works; but you are right that I can't be sure that there is only one bookmark in the paragraph, but I can be sure that no bookmark will contain other bookmarks. Since we are looking for the bookmark by name in that method I can be sure that I am getting the one bookmark's text that I am looking for. Does that sound right?

Actually, in looking at your solution, I think maybe using GetBookmarkContent() is all I need. Is there a way to just convert TextBodyPart to string? You set GetBookmarkContent to part but never seem to use part.

bobradu
 
Posts: 9
Joined: Wed Aug 20, 2014 7:06 pm

Thu Aug 28, 2014 6:55 am

Hello,

Thanks for your response.
Sound right!
Sorry that I forget to remove the sentence which is for my testing when attached the codes, I have modified it.
The GetBookmarkContent() method returns the TextBodyPart object includes all the contents of the bookmark, which can't be converted to string, you need to iterate the bodyitems to get the text of the bookmark as my solution.
Thanks,
Gary
E-iceblue support team
User avatar

Gary.zhang
 
Posts: 1380
Joined: Thu Apr 04, 2013 1:30 am

Return to Spire.Doc