DocumentBuilder MoveTo a StructuredDocumentTag

I am trying to replace a structured document tag with another - in the same location. How does one go about doing this? Attached you will find a sample document; it has a table,a single row, and two cells. I would like to replace the SDT that says “Click here to enter text” with a check box content control, list box, drop down, date, etc. Here is the code I am trying (in a console app):

using System.IO;
using Aspose.Words;
using Aspose.Words.Markup;
namespace ReplaceSdt
{
    class Program
    {
        static void Main(string[] args)
        {
            Document doc = new Document(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + "\SdtTest.docx");
            DocumentBuilder builder = new DocumentBuilder(doc);
            NodeCollection sdts = doc.GetChildNodes(NodeType.StructuredDocumentTag, true);
            // Create a new Sdt
            StructuredDocumentTag newSdt = new StructuredDocumentTag(doc, SdtType.Checkbox, MarkupLevel.Inline);
            newSdt.Tag = "q:abc";
            // Move to the sdt to replace (in this example there is only one in the document)
            // (this blows up)
            builder.MoveTo(sdts[0].ParentNode);
            // Insert the new node
            builder.InsertNode(newSdt);
            // Remove the old no longer used node
            sdts[0].Remove();
        }
    }
}

Thank you,
Sherri

Hi Sherri,

Thanks for your inquiry. You can achieve this after using the following code:

Document doc = new Document(MyDir + @"SdtTest.docx");
StructuredDocumentTag oldSdt = null;
foreach (StructuredDocumentTag sdt in doc.GetChildNodes(NodeType.StructuredDocumentTag, true))
{
    if (sdt.Tag.Equals("q:abc"))
    {
        oldSdt = sdt;
        break;
    }
}
StructuredDocumentTag newSDT = new StructuredDocumentTag(doc, oldSdt.SdtType, oldSdt.Level);
((Cell)newSDT.FirstChild).FirstParagraph.Runs[0].Text = "This is new SDT";
oldSdt.ParentNode.InsertAfter(newSDT, oldSdt);
oldSdt.Remove();
doc.Save(MyDir + @"15.9.0.docx");

Hope, this helps.

Best regards,

Thank you for your response. I’m sorry I wasn’t clear - I am trying to insert a new Sdt of a different type. So currently I have a “placeholder” content control of type textbox - I would like to insert a checkbox, dropdown, etc. in its place. Your code works perfectly if they are the same type - but when I try to insert a new one of a different type, I get the following:

An unhandled exception of type ‘System.ArgumentException’ occurred in Aspose.Words.dll

Additional information: Cannot insert a node of this type at this location.

The code:

StructuredDocumentTag newSDT = new StructuredDocumentTag(doc, SdtType.Checkbox, oldSdt.Level);
Thanks,
Sherri

Hi Sherri,

Thanks for your inquiry. You need to first check what is the value of oldSdt.Level. The MarkupLevel enumeration specifies the level in the document tree where a particular StructuredDocumentTag can occur. Here are the details:

Member Name Description Value
Unknown Specifies the unknown or invalid value. 0
Inline The element occurs at the inline level (e.g. among as runs of text). 1
Block The element occurs at the block level (e.g. among tables and paragraphs). 2
Row The element occurs among rows in a table. 3
Cell The element occurs among cells in a row. 4

In your case the old SDT is a Cell level control; in this case you can insert a Cell node and insert checkbox control inside the first paragraph as follows:

Document doc = new Document(MyDir + @"SdtTest.docx");
StructuredDocumentTag oldSdt = null;
foreach (StructuredDocumentTag sdt in doc.GetChildNodes(NodeType.StructuredDocumentTag, true))
{
    if (sdt.Tag.Equals("q:abc"))
    {
        oldSdt = sdt;
        break;
    }
}
if (oldSdt.Level.Equals(MarkupLevel.Cell))
{
    StructuredDocumentTag newSDT = new StructuredDocumentTag(doc, SdtType.Checkbox, MarkupLevel.Inline);
    newSDT.Checked = true;
    Cell newCell = (Cell)((Cell)oldSdt.FirstChild).Clone(false);
    newCell.AppendChild(new Paragraph(doc));
    newCell.FirstParagraph.AppendChild(newSDT);
    oldSdt.ParentNode.InsertAfter(newCell, oldSdt.PreviousSibling);
    oldSdt.Remove();
}
doc.Save(MyDir + @"15.9.0.docx");

Hope, this helps.

Best regards,