TheMethod
TheMethod

Reputation: 3001

Changing Word Document XML

What I am doing is trying to change the value of a Microsoft Office Word documents XML and save it as a new file. I know that there are SDK's that I could use to make this easier but the project I am tasked with maintaining is doing things this way and I was told I had to as well.

I have a basic test document with two placeholders mapped to the following XML:

<root>
  <element>
     Fubar
  </element>
  <second>
     This is the second placeholder
  </second>
</root>

In my test project I have the following:

string strRelRoot = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
//the word template
byte[] buffer = File.ReadAllBytes("dev.docx");
MemoryStream stream = new MemoryStream(buffer, true);
Package package = Package.Open(stream, FileMode.Open, FileAccess.ReadWrite);
//get the document relationship
PackageRelationshipCollection pkgrcOfficeDocument = package.GetRelationshipsByType(strRelRoot);
//iterate through relationship
foreach (PackageRelationship pkgr in pkgrcOfficeDocument)
{
    if (pkgr.SourceUri.OriginalString == "/")
    {
        //uri for the custom xml
        Uri uriData = new Uri("/customXML/item1.xml", UriKind.Relative);
        //delete the existing xml if it exists
        if (package.PartExists(uriData))
        { 
            // Delete template "/customXML/item1.xml" part
            package.DeletePart(uriData);
        }
        PackagePart pkgprtData = package.CreatePart(uriData, "application/xml");
           //hard coded test data
           string xml = @"<root>
                        <element>
                            Changed
                        </element>
                        <second>
                                The second placeholder changed
                        </second>
                    </root>";
        Stream fromStream = pkgprtData.GetStream();
        //write the string
        fromStream.Write(Encoding.UTF8.GetBytes(xml),0,xml.Length);
        //destination file
        Stream dest = File.Create("test.docx");
        //write to the destination file
        for (int a = fromStream.ReadByte(); a != -1; a = fromStream.ReadByte())
        {
            dest.WriteByte((byte)a);
        }

    }
}

What is happening right now is the file test.docx is being created but it is a blank document. I'm not sure why this is happening. Any suggestions anyone could offer on this approach and/or what I am doing incorrectly would be very much appreciated. Thanks much!

Upvotes: 2

Views: 1434

Answers (1)

anton.burger
anton.burger

Reputation: 5706

After your fromStream.Write call, the stream pointer is positioned after the data you've just written. So your first call to fromStream.ReadByte is already at the end of the stream, and you read (and write) nothing.

You need to either Seek to the beginning of the stream after writing (if the stream returned by the package supports seeking), or close fromStream (to ensure the data you've written is flushed) and reopen it for reading.

fromStream.Seek(0L, SeekOrigin.Begin);

Upvotes: 2

Related Questions