【问题标题】:Saving an xml document results in corrupt file保存 xml 文档会导致文件损坏
【发布时间】:2012-03-24 01:06:14
【问题描述】:

我有一个关于如何将 xmldoc 保存为 word 文件的问题。我想打开 word 文件,使用 xmldocument 类对 undelying xml 结构进行一些操作,然后将其重新保存回 word 文件。这就是我目前正在做的事情:

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(@"E:\HelloWorld.docx", true))
                {
                   MainDocumentPart mainPart = wordDoc.MainDocumentPart;
                   var xmlDoc = new XmlDocument();
                   using (Stream partStream = part.GetStream())
                   using (XmlReader partXmlReader = XmlReader.Create(partStream))
                     xmlDoc.Load(partXmlReader);
                   //xml node manipulation here

                   xmlDoc.Save(@"E:\HelloWorld.docx");
                 }

但是,这会导致文档损坏。执行此功能的正确方法是什么?

【问题讨论】:

  • 您能否评论一下损坏的内容和您的期望:HelloWorld.Test 将是一个 XML 文件,而不是 docx,XML 无效 XML 或 HelloWorld.docx 是否损坏或您期望 HelloWorld.Test做word文档?
  • 抱歉,这是一个错字。我正在尝试打开一个 docx,使用 xmldoc 提取 xml 结构,对其进行修改,然后将其写回另一个 docx 文件。所以 HelloWorld 应该是一个 docx

标签: c# xml openxml


【解决方案1】:

OpenXML 文档不仅仅是一个 XML 文件(实际上,它是一个包含多个文件的 ZIP 存档,其中包括 XML 文件)。

你应该做的是修改你的WordprocessingDocument然后保存它(这是在using块的末尾自动完成的),而不是保存代表文档一部分的XML文件:

using (var wordDoc = WordprocessingDocument.Open(fileName, true))
{
    MainDocumentPart mainPart = wordDoc.MainDocumentPart;

    using (Stream partStream = mainPart.GetStream())
    {
        var xmlDoc = new XmlDocument();

        using (XmlReader partXmlReader = XmlReader.Create(partStream))
            xmlDoc.Load(partXmlReader);

        //xml node manipulation here

        partStream.Position = 0;

        using (XmlWriter partXmlWriter = XmlWriter.Create(partStream))
            xmlDoc.Save(partXmlWriter);
    }
}

【讨论】:

  • 我不确定是这种方法还是我的 xml 操作代码有问题,因为我看不到任何更改。基本上在操作部分,我试图从文档中删除几个运行,但它们仍然会在最后出现。
  • @JohnBaum,这段代码对我有用。你确定你完全按照我写的那样使用它(重置流的Position,然后将 XML 写入它)?除非您对我们如何处理,否则我们无法帮助您处理您的代码。您可能应该问另一个问题并将您的代码放在那里。
  • 对我来说似乎是正确的。您是否对其进行了调试以查看它是否确实删除了您认为应该删除的节点?
  • 我将如何调试它?如果这就是您的意思,则节点将从父节点中删除
【解决方案2】:

如果您已成功执行操作,您可以稍后在您的 wordDoc 变量上使用 Close() 将其保存回文件。 MSDN 声明这也会保存内容。

【讨论】:

  • 那你可能没有真正修改过文档,看我的回答。
  • 我怎样才能确定文档被修改了?
【解决方案3】:

docx 将是一个 XML 文件,而不是 DOCX。

var xmlDoc = new XmlDocument();
... 
xmlDoc.Save(@"E:\HelloWorld.docx");

您需要的是创建新的 WordprocessingDocument 或使用您修改过的 XML 更新现有的。有点意思

using (StreamWriter sw =
    new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
    {
        xmlDoc.Save(sw);
    }

在 MSDN 中查看更多示例:http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.document.aspx

【讨论】:

  • 这会用我的更改创建一个 docx 文件吗?它在哪里创建?
  • MSDN 示例显示/解释了如何做到这一点,但请参阅 svick 的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多