Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bookmark deletion using xml

Tags:

c#

openxml

I am trying to edit a word doc using openxml and c#. I have the following xml structure for the doc:

    <w:bookmarkStart w:name="HelloWorld" w:id="0" />
    <w:bookmarkStart w:name="_GoBack" w:id="1" />
    <w:r w:rsidRPr="00874DDF">
      <w:rPr>
        <w:rFonts w:ascii="Arial" w:hAnsi="Arial" />
        <w:b />
        <w:bCs />
        <w:sz w:val="28" />
        <w:szCs w:val="28" />
        <w:u w:val="single" />
      </w:rPr>
      <w:t>Hello World:</w:t>
    </w:r>
  </w:p>
  <w:p w:rsidRPr="00583A84" w:rsidR="00CB71E3" w:rsidP="00CB71E3" w:rsidRDefault="00CB71E3">
    <w:pPr>
      <w:spacing w:line="260" w:lineRule="atLeast" />
      <w:jc w:val="both" />
      <w:rPr>
        <w:rFonts w:ascii="Arial" w:hAnsi="Arial" />
        <w:color w:val="000000" />
      </w:rPr>
    </w:pPr>
    <w:r w:rsidRPr="00583A84">
      <w:rPr>
        <w:rFonts w:ascii="Arial" w:hAnsi="Arial" />
        <w:color w:val="000000" />
      </w:rPr>
      <w:t>HelloWorld.</w:t>
    </w:r>
  </w:p>
  <w:bookmarkEnd w:id="0" />
  <w:bookmarkEnd w:id="1" />

I am trying to delete all the text in a bookmark in my word doc page. The xml structure however is making it impossible for me to do so. This is because the bookmark text is split between two different paragraph parent tags. How can i delete all the text between bookmark start 0 and bookmark end 0?

like image 312
John Baum Avatar asked Apr 23 '26 17:04

John Baum


1 Answers

I'm building a small project that edits text, tables and graphs in Word at my job. Using openXML this is how I would go about replacing text covered by a bookmark.

I do not know whether you have the isolation of the bookmarkStart element covered, so I included that as well.

First the code for capturing the bookmarkStart:

Dictionary<String,BookmarkStart> bookMap = new Dictionary<String, BookmarkStart>(); //a dictionary so we can lookup a bookmarkStart with it's name
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open("MyWordDocument.docx", true))
{
    var mainPart = wordDoc.MainDocumentPart; //get mainpart
    var bookmarks = mainPart.Document.Body.Descendants<BookmarkStart>(); //get all bookmarks
    foreach (BookmarkStart bookmarkStart in bookmarks) //save them to dictionary
    {   
        bookMap[bookmarkStart.Name] = bookmarkStart;
    }
    ReplaceInBookmark(bookmark["myBookmark"],"text to insert"); 
}

Then the replacing part:

public  void ReplaceInBookmark(BookmarkStart bookmarkStart, string text)
        {
            OpenXmlElement elem = bookmarkStart.NextSibling();
            while (elem != null && !(elem is BookmarkEnd))
            {
                OpenXmlElement nextElem = elem.NextSibling();
                elem.Remove();
                elem = nextElem;
            }
            bookmarkStart.Parent.InsertAfter<Run>(new Run(new Text(text)), bookmarkStart);
        }

This, I think, should do the job. But it's a copypaste with some small edits of some code I'm not at liberty to test right now, so bugs/mistakes may be present.

If you want to delete the bookmark, and it's content (not replacing it), you can either try to send an empty String or make a small change in the method. This one basically removes all the elements and then inserts a new Run with the text specified.

Good luck!

like image 184
Kaspar Kjeldsen Avatar answered Apr 26 '26 07:04

Kaspar Kjeldsen