OpenXML 替换 XmlNode 值留下残留数据

OpenXML replacing XmlNode value leaves residual data

使用下面的代码时,我得到了损坏的 xlsx 文件,可以通过从 connections.xml 文件中删除残留数据来修复该文件。 是什么导致了这个问题以及如何解决这个问题?

using (SpreadsheetDocument excelDoc = SpreadsheetDocument.Open(file.FullName, true))
{
    WorkbookPart workbookpart = excelDoc.WorkbookPart;
    ConnectionsPart connPart = workbookpart.ConnectionsPart;

    string spreadsheetmlNamespace = @"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
    NameTable nt = new NameTable();
    XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
    nsManager.AddNamespace("sh", spreadsheetmlNamespace);

    XmlDocument xdoc = new XmlDocument(nt);
    xdoc.Load(connPart.GetStream());
    XmlNode oxmlNode = xdoc.SelectSingleNode("/sh:connections/sh:connection/sh:dbPr/@connection", nsManager);

    oxmlNode.Value = oxmlNode.Value.Replace(oxmlNode.Value, "foo");
    xdoc.Save(connPart.GetStream());
}

结果 connections.xml 看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<connections xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <connection id="1" keepAlive="1" name="LCR" type="5" refreshedVersion="4" background="1" saveData="1">
    <dbPr connection="foo" command="test" commandType="1" />
    <olapPr sendLocale="1" rowDrillCount="1000" serverFill="0" serverFont="0" serverFontColor="0" />
  </connection>
</connections>y Options=2;MDX Missing Member Mode=Error;Disable Prefetch Facts=True" command="test" commandType="1"/><olapPr sendLocale="1" rowDrillCount="1000" serverFill="0" serverFont="0" serverFontColor="0"/></connection></connections>

请注意最后的残差数据。如果这个去掉了,xlsx又可以打开了。

通过添加额外的行来解决此问题,该行会在向其添加数据之前清除该部分。

...
oxmlNode.Value = oxmlNode.Value.Replace(oxmlNode.Value, newConnection);
connPart.FeedData(connPart.GetStream()); //Added
xdoc.Save(connPart.GetStream())
...

来自MSDN

Feed data into the part stream. The stream of the part will be truncated at first.

感谢 SO 相关问题部分找到了答案。特别是 OpenXML replace specific customxml part of word document.