Document Builder unable to insert content (HTML or Text)

I am trying to insert simple Text and HTML in place of a content control. Looks like it is unable to insert text or html before/after the first content control. It works if I insert text or html after/before second content control. I have attached the ik_html_01.docx as well.
ik_html_01.docx (14.1 KB)

Here is the code:

private static void insertHTML()
{
    string fileName = @"ik_html_01.docx";
    string mergeRec = "<TCSVerify><vData1>&lt;html&gt;&lt;body&gt;Testing - 12345&lt;/body&gt;&lt;/html&gt;</vData1></TCSVerify>";

    var mergeDataDoc = new XmlDocument();
    mergeDataDoc.XmlResolver = null;
    mergeDataDoc.LoadXml(mergeRec);

    AsposeWord.Document doc = new AsposeWord.Document(fileName);
    AsposeWord.DocumentBuilder builder = new AsposeWord.DocumentBuilder(doc);

    var lcXPathNodeList = mergeDataDoc.SelectNodes(@"//*[contains(text(),'<html>')][text()!='']", mcNsMgr);

    // Get xpath
    var xpath = "ns0:TCSVerify[1]/ns0:vData1";

    if (lcXPathNodeList != null)
    {
        foreach (XmlNode xPathNode in lcXPathNodeList)
        {
            var listOfSdts = doc.GetChildNodes(AsposeWord.NodeType.StructuredDocumentTag, true).Where(item => ((AsposeMarkup.StructuredDocumentTag)item).XmlMapping.XPath == xpath);

            foreach (AsposeMarkup.StructuredDocumentTag sdt in listOfSdts)
            {
                if (sdt != null)
                {
                    builder.MoveTo(sdt);

                    var html = HttpUtility.HtmlDecode(xPathNode.InnerXml);

                    builder.InsertHtml(html);

                    builder.Writeln("A whole para");

                }
            }

        }
    }

    builder.Document.Save("output1.docx");
    doc.Save("output2.docx");
}

@imran.khan1 I have simplified your code for testing purposes and as I can see content in inserted in both cases:

string html = "<html><body>Testing - 12345</body></html>";

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

var listOfSdts = doc.GetChildNodes(NodeType.StructuredDocumentTag, true);
foreach (StructuredDocumentTag sdt in listOfSdts)
{
    builder.MoveTo(sdt);
    builder.InsertHtml(html);
    builder.Writeln("A whole para");
}

doc.Save("C:\\Temp\\out.docx");

Here is the output document: out.docx (11.6 KB)

You should note that SDTs in your document are on different markup levels, the first is on the block level and the second is in the inline level:

Thanks !

That works for me. But how can I remove the SDT ? Actually, I wanted to replace the SDT with the HTML or text content. If I add the following line to the code, it works for the second content control but not for the first one.

sdt.Remove();

Complete Code:

private static void insertHTML2()
{
    var license = new AsposeWord.License();
    license.SetLicense("Aspose.Words.lic");

    string html = "<html><body>Testing - 12345</body></html>";

    AsposeWord.Document doc = new AsposeWord.Document(@"ik_html_01.docx");
    AsposeWord.DocumentBuilder builder = new AsposeWord.DocumentBuilder(doc);

    var listOfSdts = doc.GetChildNodes(AsposeWord.NodeType.StructuredDocumentTag, true);
    foreach (AsposeMarkup.StructuredDocumentTag sdt in listOfSdts)
    {
        builder.MoveTo(sdt);
        builder.InsertHtml(html);
        builder.Writeln("A whole para");
        // ADDED FOLLOWING LINE
        sdt.Remove();
    }

    doc.Save("out.docx");
}

Here is the output of the above code.
out.docx (11.4 KB)

Like I said, It didnot work for the 1st content control and removed the whole line. On the other hand, it works for the 2nd content control. Is there a different way to delete the content control that are at a block level ?

@imran.khan1 When sdt.Remove(); is called the whole SDT is removed from the document. in case of block level SDT contains text before placeholder {vData1}. When DocumentBuilder cursor is moved to block level SDT, it is moved inside SDT. So the content is inserted inside SDT and when SDT is removed whole content is removed. You can try using sdt.RemoveSelfOnly(); instead sdt.Remove();. In this case inner content of SDT is kept.

That’s not I want exactly. I want to replace the SDT with the html. After using sdt.RemoveSelfOnly(), I am getting this:

Here is some data: {vData1}Testing - 12345A whole para

I want this:

Testing - 12345A whole para

Here is the Code:

private static void insertHTML2()
{

    var license = new AsposeWord.License();
    license.SetLicense("Aspose.Words.lic");

    string html = "<html><body>Testing - 12345</body></html>";

    AsposeWord.Document doc = new AsposeWord.Document(@"ik_html_01.docx");
    AsposeWord.DocumentBuilder builder = new AsposeWord.DocumentBuilder(doc);

    var listOfSdts = doc.GetChildNodes(AsposeWord.NodeType.StructuredDocumentTag, true);
    foreach (AsposeMarkup.StructuredDocumentTag sdt in listOfSdts)
    {
        builder.MoveTo(sdt);
        builder.InsertHtml(html);
        builder.Writeln("A whole para");
        if (sdt.Level == AsposeMarkup.MarkupLevel.Inline)
        {
            sdt.Remove();
        }
        else
        {
            sdt.RemoveSelfOnly();
        }
    }

    doc.Save("out.docx");
}

@imran.khan1 Please try using the following code:

string html = "<html><body>Testing - 12345</body></html>";

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

var listOfSdts = doc.GetChildNodes(NodeType.StructuredDocumentTag, true);
foreach (StructuredDocumentTag sdt in listOfSdts)
{
    sdt.RemoveAllChildren();
    // Make sure the is node we can move to in SDT.
    if (sdt.Level == MarkupLevel.Block)
        sdt.AppendChild(new Paragraph(doc));
    else if(sdt.Level == MarkupLevel.Inline)
        sdt.AppendChild(new Run(doc));

    builder.MoveToStructuredDocumentTag(sdt, 0);
    builder.InsertHtml(html);
    // NOTE: it is no allowed to insert paragraphs in inline SDT.
    builder.Write("A whole para");

    sdt.RemoveSelfOnly();
}

doc.Save("C:\\Temp\\out.docx");

Your code is throwing syntax error (attached)

Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from ‘Aspose.Words.Document’ to ‘System.Collections.Generic.IEnumerable<DocumentFormat.OpenXml.OpenXmlElement>’ InsertHTML

@imran.khan1 Please try using fully qualified names:

// Make sure the is node we can move to in SDT.
if (sdt.Level == MarkupLevel.Block)
    sdt.AppendChild(new Aspose.Words.Paragraph(doc));
else if (sdt.Level == MarkupLevel.Inline)
    sdt.AppendChild(new Aspose.Words.Run(doc));

@alexey.noskov Your code is adding an extra line to the output.

Input

Output

Thanks
Imran

@imran.khan1
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): WORDSNET-26419

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

We have a paid support account. How can I transfer this ticket to the paid account ?

@imran.khan1 You should escalate the issue in the Paid Support Helpdesk . Then my colleagues from Paid Support team will raise the issue priority.

I have entered the ticket using Paid support account.

https://helpdesk.aspose.com/tickets.php?id=9653

@imran.khan1 My colleagues from Paid Support team will raise the issue priority. We will keep you updated and let you know once the issue is resolved or we have more information for you.

1 Like

The issues you have found earlier (filed as WORDSNET-26419) have been fixed in this Aspose.Words for .NET 24.2 update also available on NuGet.