Search code examples
c#xmlms-wordopenxml

OpenXML replace specific customxml part of word document


I am using OpenXML SDK ver 2 to manipulate some word documents. The documents currently have custom xml parts and what I want to do is replace the xml for the parts specifically.

I know I can do something like this to access the customxml parts of a document:

Dim mainStream As New MemoryStream()
Dim buffer As Byte() = File.ReadAllBytes(Server.MapPath("myfile.docx"))
mainStream.Write(buffer, 0, buffer.Length)

Try
  Using mainDocument As WordprocessingDocument = WordprocessingDocument.Open(mainStream, True)

  MainDocumentPart mainPart = mainDocument.MainDocumentPart;
  'collection of custom xml parts
   Dim parts = mainPart.CustomXmlParts
   For Each part As CustomXmlPart In parts
     'how do I replace the xml here??
   Next

But as you can see I'm not sure how to replace the XML of the part. My document has two XML parts called item1.xml and item2.xml. I want to replace the XML in those parts. I know I can use .DeleteParts() to remove the existing xml parts and I can use AddCustomXmlPart() to create new parts but I don't want to do that. I simply want to replace the XML for the existing parts.

Could anyone suggest how I could do this? Any advice is appreciated.

Thank you.

Edit oops forgot the code tags


Solution

  • Use the FeedData() method of the CustomXmlPart instance to replace the XML of the custom xml part. The FeedData() method at first truncates the stream of the part, then writes the new data to the part stream. So, you could use this method to replace the XML in an existing custom xml part.

    MainDocumentPart mainPart = mainDocument.MainDocumentPart;
    
    Dim parts = mainPart.CustomXmlParts
    
    For Each part As CustomXmlPart In parts
    
      Dim ms As New MemoryStream
      Dim xtw As New XmlTextWriter(ms, Encoding.UTF8)
    
      ' Create your xml.'
    
      xtw.WriteStartDocument() 
      xtw.WriteStartElement("bla")
      xtw.WriteEndElement()
      xtw.WriteEndDocument()
      xtw.Flush()
    
      ms.Seek(0, SeekOrigin.Begin)
    
      part.FeedData(ms) ' Replace old xml in part stream.'
    
      xtw.Close()    
    
    Next