内存中 XML 操作

发布于 2024-09-06 14:53:53 字数 1354 浏览 13 评论 0原文

我正在尝试在已打开到 MemoryStream 中的 OpenXML Word 文档中进行查找和替换。

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 产生任何影响。

我找到了这个博客作者: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 属性或类似的东西。我看不到任何从节点获取文本或更新它们的方法。我尝试强制转换节点,但没有编译。

我的方向正确吗?或者有更简单的方法吗?任何指点将不胜感激,谢谢。

I'm trying to do a find and replace in an OpenXML word document which I've openened into a 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!");
}

This doesn't work. I'm not sure why, but manipulating the document in this way doesn't seem
to have any affect on the MemoryStream.

I found this blog by Eric White which does something similar, but I still can't quite get it. He uses an XDocument, so I've got something like the following:

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

This finds the right nodes in my document, but the problem is now I can't work out how to change the text. The System.Xml.Linq.XNodes which I end up with this way (instead of the DocumentFormat.OpenXml.Wordprocessing.Text nodes I really want) don't have an InnerText or Value property or anything like that. I can't see any way to get the text from the nodes, or update them. I tried casting the node but that didn't compile.

Am I even going in the right direction? Or is there an easier way? Any pointers would be very much appreciated, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

随心而道 2024-09-13 14:53:53

我终于成功了。就第一个代码片段而言,最后一行应为 placeHolder.Text 而不是 placeHolder.InnerText。不敢相信我为此浪费了 4 个小时! :(

I finally got this working. Taking the first code snippet, the last line should read placeHolder.Text and not placeHolder.InnerText. Can't believe I wasted 4 hours on that! :(

浅唱ヾ落雨殇 2024-09-13 14:53:53

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

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

To the first part (updating the MemoryStream).
You should think about the memory stream as read only as it is passed to the Open method. The parser has read through the stream and built another in memory representation that is not connected tot he input stream. You'll have to write it back out using Save.

As for manipulating an XNode's textual content you are looking for XText.Value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文