You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OpenXML和C#设置Word文档注释属性时出现打开错误

问题:设置Word文档Comments属性后打开报错,代码无执行异常

编写了一段C#代码用于设置Word文档的Comments属性,传入参数val="EMA"、prop="comments",代码执行无异常,但打开文档时出现错误。代码如下:

public void SetProperty(string val, string prop)
{
    // Define the namespaces for XPath queries.
    const string corePropertiesSchema = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";

    NameTable nt = new NameTable();
    XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
    nsManager.AddNamespace("cp", corePropertiesSchema);

    using (WordprocessingDocument wdPackage = WordprocessingDocument.Open("C:\\Users\\Dev\\OneDrive\\Documents\\Doc1.docx", true))
    {
        // Get the core properties part (core.xml).
        CoreFilePropertiesPart corePropertiesPart = wdPackage.CoreFilePropertiesPart;

        // Load the XML in the part into an XmlDocument instance.
        XmlDocument xdoc = new XmlDocument(nt);
        xdoc.Load(corePropertiesPart.GetStream());
        
        // Find the Comments property.
        string searchString = "//cp:coreProperties/cp:comments";
        XmlNode commentsNode = xdoc.SelectSingleNode(searchString, nsManager);

        if (commentsNode != null)
        {
            // If the Comments property exists, update its value.
            commentsNode.InnerText = val;
        }
        else
        {
            // If the Comments property does not exist, create it.
            XmlElement modeElement = xdoc.CreateElement("cp", prop, corePropertiesSchema);
            modeElement.InnerText = val;
            xdoc.DocumentElement.AppendChild(modeElement);
        }

        using (Stream stream = corePropertiesPart.GetStream())
        {
            // Save the changes to the core properties part.
            xdoc.Save(stream);

            searchString = string.Format("//cp:coreProperties/{0}", "cp:comments");

            XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
            if (!(xNode == null))
            {
                string propertyValue = xNode.InnerText;
            }
        }
    }
}

已使用OpenXML SDK 2.5 Office生产力工具检查文件,未发现有效信息,请问这段代码存在什么问题?


问题分析与解决

核心问题出在XML内容的保存方式上,直接调用corePropertiesPart.GetStream()获取流并保存XML,会导致原有文档内容和新内容混杂,破坏core.xml的结构,最终引发Word打开报错。

具体问题点

  1. 调用corePropertiesPart.GetStream()时,默认流模式为FileMode.Open,流的当前位置可能处于末尾,直接保存XML会将新内容追加到旧内容之后,生成无效的XML文档。
  2. 保存后冗余的节点查询代码无实际作用,属于不必要的操作。

修正方案

修改保存流的获取方式,使用FileMode.Create覆盖原内容,确保XML文档完整且有效:

public void SetProperty(string val, string prop)
{
    const string corePropertiesSchema = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties";

    NameTable nt = new NameTable();
    XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
    nsManager.AddNamespace("cp", corePropertiesSchema);

    using (WordprocessingDocument wdPackage = WordprocessingDocument.Open("C:\\Users\\Dev\\OneDrive\\Documents\\Doc1.docx", true))
    {
        CoreFilePropertiesPart corePropertiesPart = wdPackage.CoreFilePropertiesPart;
        XmlDocument xdoc = new XmlDocument(nt);
        xdoc.Load(corePropertiesPart.GetStream());
        
        string searchString = "//cp:coreProperties/cp:comments";
        XmlNode commentsNode = xdoc.SelectSingleNode(searchString, nsManager);

        if (commentsNode != null)
        {
            commentsNode.InnerText = val;
        }
        else
        {
            XmlElement modeElement = xdoc.CreateElement("cp", prop, corePropertiesSchema);
            modeElement.InnerText = val;
            xdoc.DocumentElement.AppendChild(modeElement);
        }

        // 关键修改:使用FileMode.Create覆盖原内容,确保XML结构正确
        using (Stream stream = corePropertiesPart.GetStream(FileMode.Create, FileAccess.Write))
        {
            xdoc.Save(stream);
        }
    }
}

额外优化建议

  • 由于传入的prop参数固定为"comments",可以直接在代码中写死"comments",避免参数传递可能带来的错误。
  • 移除保存后冗余的节点查询代码,减少不必要的性能开销。

内容的提问来源于stack exchange,提问作者Leon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:53:18