简体   繁体   中英

How do I overwrite a DOCX XML file with C#?

I'm stuck. The goal is to change reviewer names in MS Word track changes using a C# tool, only if the corresponding date attribute is after a given date. The variable string docPath is passed to the method changeRevAuthor . docPath represents the opened DOCX file. The file MUST be opened when it is passed because the tool also upsaves all DOC files to DOCX before running the method.

The author names ARE changed and the date is confirmed correctly in the XML file. We tested this by saving the XML to a static path. However, what I need to do is actually overwrite the existing XML file, instead of pulling it out and saving it somewhere else. Here is the existing method:

    private void changeRevAuthor(string docPath)
    {
        using (Stream stream = System.IO.File.Open(docPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {  
            stream.Seek(0, SeekOrigin.End); 
            XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
            WordprocessingDocument document = WordprocessingDocument.Open(stream, false);
            XDocument mainDocumentXDoc = document.MainDocumentPart.GetXDocument();          
            var nodes = mainDocumentXDoc.Descendants().Where(x => x.Attributes(w + "author").Count() > 0);
            var currentdate = "2016-06-21";

            foreach (XElement node in nodes)
            {
                var date = node.Attribute(w + "date").ToString().Substring(8, 10);
                if (DateTime.Parse(date) < DateTime.Parse(currentdate))
                {
                    node.SetAttributeValue(w + "author", "LUZ");
                    Debug.WriteLine(date);
                }                   
            }
            mainDocumentXDoc.Save(document.MainDocumentPart.GetStream(FileMode.Create));

        }
    }

From research, I believe the final line should do the trick: mainDocumentXDoc.Save(document.MainDocumentPart.GetStream(FileMode.Create));

However, this returns the following error:

'An unhandled exception of type 'System.IO.IOException' occurred in System.IO.Packaging.dll Additional information: Cannot get stream with FileMode.Create, FileMode.CreateNew, FileMode.Truncate, FileMode.Append when access is FileAccess.Read.'

When I change it to FileAccess.Write or FileAccess.ReadWrite , I receive the following error:

'Additional information: The process cannot access the file 'C:\\Users....\\Desktop\\C# Test\\Results\\newtest.docx' because it is being used by another process.'

Where do I go from here?

Thanks Luke

This solves your issue:

void changeRevAuthor (string docPath)
{
  XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
  WordprocessingDocument document = WordprocessingDocument.Open(docPath, true);
  XDocument mainDocumentXDoc = document.MainDocumentPart.GetXDocument();

  var nodes = mainDocumentXDoc.Descendants().Where(x => x.Attributes(w + "author").Count() > 0);

  foreach (XElement node in nodes)
  {
    // ...
    node.SetAttributeValue(w + "author", "LUZ");        
  }
  mainDocumentXDoc.Save(document.MainDocumentPart.GetStream(FileMode.Create));
}

but is incomplete .

You should also modify word\\comments and docProps\\core package parts, not only word\\document .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM