在word文档中编辑自定义XML部分有时会破坏文档

我们有一个系统可以在Word文档中存储一些自定义模板数据。 有时,更新此数据会导致Word抱怨文档已损坏。 发生这种情况时,如果我解压缩docx文件并将内容与先前版本进行比较,则唯一的区别似乎是customXML\item.xml文件中的预期更改。 如果我使用7zip重新压缩内容,它似乎工作正常(Word不再抱怨文档已损坏)。

(简化)代码:

 void CreateOrReplaceCustomXml(string filename, MyCustomData data) { using (var doc = WordProcessingDocument.Open(filename, true)) { var part = GetCustomXmlParts(doc).SingleOrDefault(); if (part == null) { part = doc.MainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml); } var serializer = new DataContractSerializer(typeof(MyCustomData)); using (var stream = new MemoryStream()) { serializer.WriteObject(stream, data); stream.Seek(0, SeekOrigin.Begin); part.FeedData(stream); } } } IEnumerable GetCustomXmlParts(WordProcessingDocument doc) { return doc.MainDocumentPart.CustomXmlParts .Where(part => { using (var stream = doc.Package.GePart(c.Uri).GetStream()) using (var streamReader = new StreamReader(stream)) { return streamReader.ReadToEnd().Contains("Some.Namespace"); } }); } 

有什么建议?

由于重新压缩工作,似乎内容是良好的forms。

所以听起来拉链过程有问题。 因此,在7-Zip中打开损坏的docx,并记下“method”列中的值(特别是对于customXML \ item.xml)。

将该值与工作docx进行比较 – 它是相同还是不同? 方法“Deflate”有效。

我遇到了同样的问题,原来这是由于编码。 序列化/反序列化时是否已指定相同的编码?

几个建议a。 试试doc.Package.Flush(); 将数据写回自定义xml后。 湾 您可能必须删除所有自定义零件并添加新的自定义零件。 我们正在使用以下代码,它似乎工作正常。

 public static void ReplaceCustomXML(WordprocessingDocument myDoc, string customXML) { MainDocumentPart mainPart = myDoc.MainDocumentPart; mainPart.DeleteParts(mainPart.CustomXmlParts); CustomXmlPart customXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml); using (StreamWriter ts = new StreamWriter(customXmlPart.GetStream())) { ts.Write(customXML); ts.Flush(); ts.Close(); } } public static MemoryStream GetCustomXmlPart(MainDocumentPart mainPart) { foreach (CustomXmlPart part in mainPart.CustomXmlParts) { using (XmlTextReader reader = new XmlTextReader(part.GetStream(FileMode.Open, FileAccess.Read))) { reader.MoveToContent(); if (reader.Name.Equals("aaaa", StringComparison.OrdinalIgnoreCase)) { string str = reader.ReadOuterXml(); byte[] byteArray = Encoding.ASCII.GetBytes(str); MemoryStream stream = new MemoryStream(byteArray); return stream; } } } return null; //result; } using (WordprocessingDocument myDoc = WordprocessingDocument.Open(ms, true)) { StreamReader reader = new StreamReader(memStream); string FullXML = reader.ReadToEnd(); ReplaceCustomXML(myDoc, FullXML); myDoc.Package.Flush(); //Code to save file }