I have a little method that excepts a word paragraph, paragraph content and any comment content if any. As a means to track which paragraphs in the document have been processed I am attempting to add a content control around the openxml inject paragraph. It blows up and I'm not exactly sure where to start as I'm fairly new to openxml. My code sample is below:
public void Handle(Paragraph paragraph, string docPartXml, string commentsPartXml)
{
var docXml = docPartXml;
var commentsXml = commentsPartXml;
using (var res = paragraph.Range.WithComCleanup())
{
var range = res.Resource;
using (var packageStream = range.GetPackageStreamFromRange())
using (var document = WordprocessingDocument.Open(packageStream, true))
{
var pbody = document.MainDocumentPart.Document.Body;
pbody.InnerXml = docXml + "<w:p></w:p>"; // paragraphs are merged/combined w/o this
document.MainDocumentPart.Document.Save();
WordprocessingCommentsPart commentsPart = null;
if (document.MainDocumentPart.WordprocessingCommentsPart == null)
{
commentsPart = document.MainDocumentPart.AddNewPart<WordprocessingCommentsPart>();
document.MainDocumentPart.AddPart(commentsPart);
document.MainDocumentPart.Document.Save();
commentsPart = document.MainDocumentPart.WordprocessingCommentsPart;
commentsPart.Comments = new Comments();
}
if (commentsPart == null)
commentsPart = document.MainDocumentPart.WordprocessingCommentsPart;
commentsPart.Comments.InnerXml += commentsXml;
commentsPart.Comments.Save();
document.MainDocumentPart.Document.Save();
document.Package.Flush();
XDocument xdoc = OpenXmlExtensions.OpcToFlatOpc(document.Package);
var openxml = xdoc.ToString();
var validator = new OpenXmlValidator();
var errors = validator.Validate(document);
// todo - provide more detailed info for the log
foreach (var err in errors)
_logger.Warn(err.Description, "OpenXml Injection");
try
{
range.InsertXML(openxml);
}
catch (COMException e)
{
_logger.Error("Unable to insert xml into paragraph");
}
}
}
}
Replace the pbody.InnerXml = ... line of code with the following and it works fine.
pbody.RemoveAllChildren<Paragraph>();
pbody.RemoveAllChildren<SdtBlock>();
pbody.RemoveAllChildren<SdtProperties>();
var sdtBlock1 = new SdtBlock();
var sdtPr = new SdtProperties(
new SdtAlias {Val = string.Format("{0}-{1}", "CC", hash)},
new Tag {Val = string.Format("{0}-{1}", hash, "CC")});
//new Lock(){ Val = LockingValues.ContentLocked});
sdtBlock1.AppendChild(sdtPr);
var sdtContentBlock1 = new SdtContentBlock {
InnerXml = docXml};
sdtBlock1.AppendChild(sdtContentBlock1);
pbody.AppendChild( sdtBlock1);