Update SDT content control but keep styles

I have some code that replace content (based on https://docs.aspose.com/words/net/working-with-content-control-sdt/) but new value do not keep my styles.

E.g. I make a header section where I place

“bold” : <content tag 4711>“bold”.

I save my template, run my code and replace 4711 with any value.
The new document will contain the new value, but the “bold” formatting is gone.

So in general I guess I have to read old styles, and set them to the new “run” or “para”, but I can’t find any info about how to do this.

Hi Yves,

Thanks for your inquiry. It would be great if you please share following detail for investigation purposes.

  • Please attach your input Word document.
  • Please

create a standalone/runnable simple application (for example a Console
Application Project
) that demonstrates the code (Aspose.Words code) you used to generate
your output document

  • Please attach the output Word file that shows the undesired behavior.
  • Please
    attach your target Word document showing the desired behavior. You can
    use Microsoft Word to create your target Word document. I will
    investigate as to how you are expecting your final document be generated
    like.

Unfortunately,
it is difficult to say what the problem is without the Document(s) and
simplified application. We need your Document(s) and simple project to
reproduce the problem. As soon as you get these pieces of information to
us we’ll start our investigation into your issue.

Hello,
took me a while to answer this post as I worked on another project.
I add two word documents to clarify what I want to achieve.

Sample.docs contains a tag which has formatted styles.
result.docx is the result of replacing the tag content like described above.

Thanks for checking.
Yves

Hi Yves,

Thanks for sharing the detail. In your case, I suggest you please use Range.Replace method as shown below. Please let us know if you have any more queries.

Document doc = new Document(MyDir + "Sample.docx");
StructuredDocumentTag sdt = (StructuredDocumentTag)doc.GetChild(NodeType.StructuredDocumentTag, 0, true);
sdt.Range.Replace("Klicken Sie hier, um Text einzugeben.", "*content replaced. Styles still intact?*", false, false);
doc.Save(MyDir + "Out.docx");

Unfortunately I doubt this will work as I do not know the former content value.

In the example “Klicken Sie hier, um Text einzugeben.” is just the default value. That can be any text.

Hi Yves,

Thanks
for your inquiry. The shared code example works with any text value of content control. If you still face problem, please share the input document for which the shared code example is not working. I will investigate the issue on my side and provide you more information.

I may not understand your answer correctly, I open “any” document which has any fields formatted which I can address, but I do not know the current value of the field. So In your example I need to determine the old value first!?

Hi Yves,

Thanks for your inquiry. You can get the text of content control by using StructuredDocumentTag.ToString(SaveFormat.Text) method and replace it with

As per my understanding, you want to update the text of content control and keep the text formatting. Could you please share some more detail about your requirements and scenarios along with the input document and expected output documents? We will then provide you more information about your query along with code.

Hello,
thank you, I will try this. Maybe my current code can be much more simple then now.

At the moment I seek the different SDT types and do different stuff to handle it, but I always loose my formatting.

So yes, you understand correct. In result I want to replace the plaint content text value and all other formatting should remain!

My source:

/// 
/// Set the value of a chosen form field value to the defined value
/// 
/// 
/// 
public void SetContentFieldValue(string name, string value)
{
    if (string.IsNullOrEmpty(_path)) return;
    foreach (StructuredDocumentTag sdt in _document.GetChildNodes(NodeType.StructuredDocumentTag, true))
    {
        if (sdt.Tag == name && sdt.SdtType == SdtType.PlainText)
        {
            try
            {
                if (sdt.FirstChild != null)
                {
                    if (sdt.FirstChild.NodeType == NodeType.Cell)
                    {
                        var para = new Paragraph(_document);
                        var run = new Run(_document, value);
                        para.AppendChild(run);

                        var cell = (Cell)sdt.FirstChild;
                        cell.RemoveAllChildren();
                        cell.AppendChild(para);
                    }
                    if (sdt.FirstChild.NodeType == NodeType.Paragraph)
                    {
                        sdt.RemoveAllChildren();
                        var run = new Run(_document, value);
                        var para = new Paragraph(_document);
                        para.AppendChild(run);
                        sdt.AppendChild(para);
                    }
                    if (sdt.FirstChild.NodeType == NodeType.Run)
                    {
                        sdt.RemoveAllChildren();
                        var run = new Run(_document, value);
                        sdt.AppendChild(run);
                    }

                }
                else
                {
                    if (sdt.Level == MarkupLevel.Block)
                    {
                        sdt.RemoveAllChildren();
                        var run = new Run(_document, value);
                        var para = new Paragraph(_document);
                        para.AppendChild(run);
                        sdt.AppendChild(para);
                    }
                    else
                    {
                        sdt.RemoveAllChildren();
                        var run = new Run(_document, value);
                        sdt.AppendChild(run);
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.ToLog(ex.ToString(), Company, "", "TQsoft.Common.Office.Word.log");
            }
        }
    }
}

Hi Yves,

Thanks
for your inquiry. You are removing all children nodes of StructuredDocumentTag and inserting new Paragraph and Run nodes which contain the default font formatting. In your case, I suggest you following solution:

  1. Please clone the first Run node of content control and set its text to new text using Run.Text property
  2. Remove all children of content control
  3. Add the new cloned Run node to content control

Please check following code example for your kind reference. Hope this helps you.

Document doc = new Document(MyDir + "Sample.docx");
StructuredDocumentTag sdt = (StructuredDocumentTag)doc.GetChild(NodeType.StructuredDocumentTag, 0, true);
if (sdt.FirstChild.NodeType == NodeType.Run)
{
    Run newRun = (Run)((Run)sdt.FirstChild).Clone(true);
    newRun.Text = "Some new text";
    sdt.RemoveAllChildren();
    sdt.AppendChild(newRun);
}
doc.Save(MyDir + "Out.docx");

Thank you for sour sample.

Does this mean I do not have to handle NodeType.Cell, NodeType.Paragraph, NodeType.Run and MarkupLevel.Block in my code anymore with your solution??

Hi Yves,

Thanks
for your inquiry. If the content control contains Cell and Paragraph node, you need to get the first Run node of Paragraph/Cell node and then replace its text as shared in my previous post.

If you want to replace the text of table’s cell, please use Cell.FirstParagraph.RemoveAllChildren method to remove all children of paragraph and then append the clone Run node to Cell.FirstParagraph.

If you still face problem, please share your input and expected output document here for our reference. We will then provide you more information on this along with code.