内存中的XML操作

时间:2010-06-21 15:43:42

标签: xml openxml linq-to-xml memorystream file-manipulation

我正在尝试查找并替换OpenXML word文档,我将其打开为MemoryStream

using (WordprocessingDocument _document = WordprocessingDocument.Open(_ms, true))
{
    var placeHolder = _document.MainDocumentPart.Document
                          .Descendants<DocumentFormat.OpenXml.Wordprocessing.Text>()
                          .Where(node => node.InnerText.Contains("***PlaceHolderText***"))
                          .FirstOrDefault();

    placeHolder.InnerText.Replace("***PlaceHolderText***", "hello world!");
}

这不起作用。我不知道为什么,但以这种方式操纵文件看起来并不像 对MemoryStream

产生任何影响

我发现this blog by Eric White做了类似的事情,但我仍然无法理解。他使用了XDocument,所以我得到了类似的内容:

XDocument doc = _document.MainDocumentPart.GetXDocument(); // this is an extension method
var textNodes = doc.DescendantNodes().Where(n => n.NodeType == XmlNodeType.Text);

这在我的文档中找到了正确的节点,但问题是现在我无法弄清楚如何更改文本。以这种方式结束的System.Xml.Linq.XNodes(而不是我真正想要的DocumentFormat.OpenXml.Wordprocessing.Text个节点)没有InnerTextValue属性或类似的东西。我看不到从节点获取文本或更新它们的任何方法。我尝试过铸造节点,但是没有编译。

我是否朝着正确的方向前进?或者有更简单的方法吗?任何指针都非常感谢,谢谢。

2 个答案:

答案 0 :(得分:1)

到第一部分(更新MemoryStream)。 您应该将内存流视为只读,因为它传递给Open方法。解析器已读取流并在内存表示中构建另一个未与输入流连接的表示。您必须使用Save将其写回来。

至于操纵XNode的文字内容,您正在寻找XText.Value

答案 1 :(得分:1)

我终于有了这个工作。获取第一个代码段后,最后一行应为placeHolder.Text而不是placeHolder.InnerText。不敢相信我浪费了4个小时! :(