Heading 1 format auto number for document content variables

Refer attached suppliertemplate.dotx file. In this contract is one content variable. For this Heading 1 formatting is applied.

With program inserting another word document at this content variable. But contract field is not getting continuous number as 3 in output.docx file, its starting from 1.WordNumbering.zip (87.4 KB)

Thanks
Snehal

@snehalghute since you are inserting the new header in an SDT this is the expected behavior. Lists cannot be continued from outside of a SDT to inside it, using Aspose.Words API or MS Word application.
Therefore, if you want to continue the numeration, you must set the corresponding starting number to the list, for your case you must modify your code adding the following lines:

...
Document docToInsert = new Document("C:\\Temp\\input.docx");
builder.InsertDocument(docToInsert, ImportFormatMode.UseDestinationStyles);

var firstHeading = contentControl.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().FirstOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1 && p.IsListItem);
if (firstHeading != null)
{
    firstHeading.ListFormat.List.ListLevels[0].StartAt = 3;
    firstHeading.ListFormat.List.IsRestartAtEachSection = true;
}
...

Thanks for quick reply.

firstHeading.ListFormat.List.ListLevels[0].StartAt = 3; Here this number can be anything… How can I get next number from MS-Word which needs to be applied to the list?

@snehalghute you need to find the previous list item and get the label value of it. Please check the following code:

Document baseDoc = new Document("C:\\Temp\\input.dotx");
DocumentBuilder builder = new DocumentBuilder(baseDoc);
var contentControls = baseDoc.GetChildNodes(NodeType.StructuredDocumentTag, true);

baseDoc.UpdateListLabels();

foreach (StructuredDocumentTag contentControl in contentControls)
{

    if (contentControl.SdtType == SdtType.BuildingBlockGallery)
    {
        Run firstChild = null;
        if (contentControl.HasChildNodes)
        {
            if (contentControl.FirstChild.NodeType == NodeType.Paragraph)
            {
                contentControl.RemoveAllChildren();

                firstChild = new Run(baseDoc);

                Paragraph paragraph = new Paragraph(baseDoc);
                paragraph.AppendChild(firstChild);
                contentControl.AppendChild(paragraph);
            }
            else
            {
                firstChild = contentControl.GetChild(NodeType.Run, 0, true) as Run;
                contentControl.RemoveAllChildren();
                contentControl.AppendChild(firstChild);
            }
        }
        else
        {
            firstChild = new Run(baseDoc);
            contentControl.AppendChild(firstChild);
        }

        builder.MoveTo(firstChild);


        Document docToInsert = new Document("C:\\Temp\\input.docx");
        builder.InsertDocument(docToInsert, ImportFormatMode.UseDestinationStyles);

        var listStartAt = 1;

        var prevListItem = GetPreviousListHeading(contentControl);
        if (prevListItem != null)
        {
            listStartAt = prevListItem.ListLabel.LabelValue + 1;
        }


        var firstHeading = contentControl.GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().FirstOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1 && p.IsListItem);
        if (firstHeading != null)
        {
            firstHeading.ListFormat.List.ListLevels[0].StartAt = listStartAt;
            firstHeading.ListFormat.List.IsRestartAtEachSection = true;
        }
    }
}

baseDoc.Save("C:\\Temp\\output.docx");
private static Paragraph GetPreviousListHeading(Node from)
{
    if (from == null || from.NodeType == NodeType.Body)
    {
        return null;
    }

    var previous = from.PreviousSibling;
    while(previous != null)
    {
        if (previous.NodeType == NodeType.Paragraph)
        {
            // Idealy you should add this verification ((Paragraph)previous).ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1, but your paragraphs are not formated as Headdings
            if (((Paragraph)previous).IsListItem)
            {
                return (Paragraph)previous;
            }
        }

        if (previous is CompositeNode)
        {
            var listItem = ((CompositeNode)previous).GetChildNodes(NodeType.Paragraph, true).Cast<Paragraph>().LastOrDefault(p => p.ParagraphFormat.StyleIdentifier == StyleIdentifier.Heading1 && p.IsListItem);
            if (listItem != null)
            {
                return listItem;
            }
        }

        previous = previous.PreviousSibling;
    }

    return null;
}

TestData.zip (52.4 KB)

Above code is not solving all scenarios. Please check attached template and word document file.

@snehalghute Regarding the current output, I have detected a bug in the list inside the SDT. However, with respect to the numeration of the list items that appear after the SDT, you are currently getting the expected result. As I mentioned before, SDT elements are “decoupled” from the rest of the document items. SDT controls are not designed to support the feature that you require.
output.docx (23.3 KB)

I am currently looking for a workaround that fits your current scenario.

@snehalghute
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-25394

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.