This is my first OpenXML project. I am trying to edit the CustomXML file of a docx file. I am trying to change this:
<?xml version="1.0" encoding="UTF-8"?>
<PERSON>
<NAMETAG>NAME</NAMETAG>
<DOBTAG>DOB</DOBTAG>
<SCORE1TAG>SCORE1</SCORE1TAG>
<SCORE2TAG>SCORE2</SCORE2TAG>
</PERSON>
To this:
<?xml version="1.0" encoding="UTF-8"?>
<PERSON>
<NAMETAG>John Doe</NAMETAG>
<DOBTAG>01/01/2020</DOBTAG>
<SCORE1TAG>90.5</SCORE1TAG>
<SCORE2TAG>100.0</SCORE2TAG>
</PERSON>
I would prefer to not use search and replace but instead navigate the WordprocessingDocument to find the correct properties to modify. I tried to do a whole delete/add but that corrupted the file and did not work. Here is that code:
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
byte[] byteArray = File.ReadAllBytes(@"C:\Simple_Template.docx");
using (MemoryStream stream = new MemoryStream())
{
stream.Write(byteArray, 0, (int)byteArray.Length);
WordprocessingDocument doc = WordprocessingDocument.Open(stream, true);
doc.MainDocumentPart.DeleteParts<CustomXmlPart>(doc.MainDocumentPart.CustomXmlParts);
string newcustomXML = @"<?xml version=""1.0\"" encoding=""UTF-8\""?><Person><NAMETAG>John Doe</NAMETAG><DOBTAG>DOB</DOBTAG><SCORE1TAG>90.5</SCORE1TAG><SCORE2TAG>100.0</SCORE2TAG></PERSON>";
CustomXmlPart xmlPart = doc.MainDocumentPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
byte[] byteArrayXML = Encoding.UTF8.GetBytes(newcustomXML);
using (MemoryStream xml_strm = new MemoryStream(byteArrayXML))
{
xmlPart.FeedData(xml_strm);
}
doc.MainDocumentPart.Document.Save();
doc.Close();
File.WriteAllBytes(@"C:\Simple_Template_Replace.docx", stream.ToArray());
}
}
I have also tried to navigate through the structure but I am having a hard time figuring out where in the WordprocessingDocument object contains the actual values that I need to modify. Ideally, I would like something like this psuedo-code:
doc.MainDocumentPart.CustomXMLPart.Select("NAMETAG") = "John Doe"
--------Follow On----------
The answer below worked well without a Namespace. Now I would like to add one. This is the new XML:
<?xml version="1.0"?><myxml xmlns="www.mydomain.com">
<PERSON>
<NAMETAG>NAME</NAMETAG>
<DOBTAG>DOB</DOBTAG>
<SCORE1TAG>SCORE1</SCORE1TAG>
<SCORE2TAG>SCORE2</SCORE2TAG>
</PERSON>
</myxml>
I have adjusted the code to the following but the SelectSingleNode call is returning NULL. Here is the updated code:
XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDocument.NameTable);
mgr.AddNamespace("ns", "www.mydomain.com");
string name_tag = xmlDocument.SelectSingleNode("/ns:myxml/ns:PERSON/ns:NAMETAG", mgr).InnerText;
I was able to fix this myself. I did not realize that you need to include "ns:" with every element. I still thought that I would be able to pass in String.Empty into my AddNamespace and then I would not have to do it. But this will work for now.