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.
CodePudding user response:
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! :(
CodePudding user response:
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.