wordpress hit counter
Replacing bookmarks with content from a new word document - OpenXML Developer - Blog - OpenXML Developer
Goodbye and Hello

OpenXmlDeveloper.org is Shutting Down

There is a time for all good things to come to an end, and the time has come to shut down OpenXmlDeveloper.org.

Screen-casts and blog posts: Content on OpenXmlDeveloper.org will be moving to EricWhite.com.

Forums: We are moving the forums to EricWhite.com and StackOverflow.com. Please do not post in the forums on OpenXmlDeveloper.org. Instead, please post in the forums at EricWhite.com or at StackOverflow.com.

Please see this blog post for more information about my plans moving forward.  Cheers, Eric

Replacing bookmarks with content from a new word document

Replacing bookmarks with content from a new word document

Rate This
  • Comments 14

Article By - Godha G.N, Sonata Software Limited

 

This article demonstrates how to replace the contents of a new document at a bookmark of the original document.

 

When Sanjay and I were at the Open XML workshop in Spain, an attendee came up with a similar request and that got me to do this write-up. This article gives a simple way of replacing the contents from a new word document at the bookmark of the original document, but we can think of as many ways of complicating the matter and find better ways of solving them.

 

Bookmarks can be placed in word document at desired locations, when this is done the <w:bookmarkStart/> element and the <w:bookmarkEnd/> element are inserted into the paragraph. Text may or may not exist within these start and end elements. For text from another new document to be replaced at this bookmark, these start and end bookmark elements are searched in the document.xml of the original word document and replaced with the text from the document.xml of the new word document.

 

The following steps give details to do the same.

 

Open and read the document.xml of the original word document –

XmlDocument originalXmlDocument;

System.IO.Packaging.PackagePart originalDocumentPart = null;

System.IO.Packaging.Package originalDocPackage;

 

const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

originalDocPackage = System.IO.Packaging.Package.Open(originalDocFileName, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);

// Get the main document part (document.xml).

foreach (System.IO.Packaging.PackageRelationship relationship in originalDocPackage.GetRelationshipsByType(documentRelationshipType))

{

      Uri documentUri = System.IO.Packaging.PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);

      originalDocumentPart = originalDocPackage.GetPart(documentUri);

 

      // There is only one document.

break;

}

 

//  Manage namespaces to perform Xml XPath queries.

NameTable nt = new NameTable();

XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(nt);

xmlNamespaceManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

 

originalXmlDocument = new XmlDocument();

originalXmlDocument.Load(originalDocumentPart.GetStream());

 

Open and read the document.xml of the new word document –

const string documentRelationshipType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";

System.IO.Packaging.Package package = System.IO.Packaging.Package.Open(secondDocFileName, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);

System.IO.Packaging.PackagePart documentPart = null;

 

// Get the main document part (document.xml).

foreach (System.IO.Packaging.PackageRelationship relationship in package.GetRelationshipsByType(documentRelationshipType))

{

Uri documentUri = System.IO.Packaging.PackUriHelper.ResolvePartUri(new Uri("/", UriKind.Relative), relationship.TargetUri);

documentPart = package.GetPart(documentUri);

 

      // There is only one document.

      break;

}

 

//  Manage namespaces to perform Xml XPath queries.

NameTable nt = new NameTable();

XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(nt);

xmlNamespaceManager.AddNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

 

XmlDocument xmlDocument = new XmlDocument();

xmlDocument.Load(documentPart.GetStream());

 

Read the content of text from the paragraph of the new word document and store it in a string variable –

XmlNodeList paragraphNodes = xmlDocument.SelectNodes("//w:body/w:p/w:r/w:t", xmlNamespaceManager);

string text = "";

foreach (XmlNode node in paragraphNodes)

{

text = text + node.InnerText;

}

 

Read the bookmark start and end elements of the original word document, remove them and place the content of the new word document in its position –

XmlNode bookMarkStartNode = originalXmlDocument.SelectSingleNode("//w:bookmarkStart", xmlNamespaceManager);

if (bookMarkStartNode.NextSibling.Name == "w:r")

{

bookMarkStartNode.NextSibling.RemoveChild(bookMarkStartNode.NextSibling.LastChild);

 

XmlElement textElement = originalXmlDocument.CreateElement("w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

                    bookMarkStartNode.NextSibling.AppendChild(textElement);

 

      XmlNode textNode = originalXmlDocument.CreateNode(XmlNodeType.Text, "w:t", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

      textNode.Value = text;

      textElement.AppendChild(textNode);

}

XmlNode bookMarkEndNode = originalXmlDocument.SelectSingleNode("//w:bookmarkEnd", xmlNamespaceManager);

 

XmlNode parentNodeOfBookMark = bookMarkStartNode.ParentNode;

 

parentNodeOfBookMark.RemoveChild(bookMarkStartNode);

parentNodeOfBookMark.RemoveChild(bookMarkEndNode);

 

Save the changes made to the original word document –

originalXmlDocument.Save(originalDocumentPart.GetStream());

 

Close both the original and new word documents –

package.Close();

originalDocPackage.Close();

 

The example demo is attached with the article as a zip file.

 

Attachment: BookMarkExample.zip
Page 1 of 1 (14 items)