Hello,
I have an issue with Aspose.Words when I want to insert one document into another. Structure of the parent document is that it has only one content control (INCLUDE_DOCUMENTS) in front of which I want to insert another document which has 2 sections and for each section Header is different.
After the document is inserted last Header of inserted document is lost. Please check the code snippet below and suggest a solution if there is one.
I am using Aspose.Words 16.8.0 in production, but in this example same outcome is with version 18.3.0.
Please find attached documents for testing resource.zip (27.6 KB)
public class Program
{
public static void Main(string[] args)
{
try
{
Document parentDocument = new Document("./resource/INCLUDED_MASTER.docx");
Document documentToInsert = new Document("./resource/SectionHeaders.docx");
StructuredDocumentTag nodeToInsertBefore = GetFirstChild(parentDocument.Document, @"^INCLUDE_DOCUMENTS$");
if (nodeToInsertBefore != null)
{
DocumentBuilder builder = new DocumentBuilder(parentDocument);
Paragraph newParagraph = new Paragraph(parentDocument);
InsertNodeBefore(newParagraph, nodeToInsertBefore);
builder.MoveTo(newParagraph);
documentToInsert.EnsureMinimum();
builder.InsertDocument(documentToInsert, ImportFormatMode.UseDestinationStyles);
parentDocument.LastSection.PageSetup.SectionStart =
documentToInsert.LastSection.PageSetup.SectionStart;
// Removes last empty paragraph added by Aspose on inserted content
Paragraph lastInsertedParagraph =
nodeToInsertBefore.PreviousSibling as Paragraph;
if (lastInsertedParagraph != null &&
string.IsNullOrEmpty(lastInsertedParagraph.GetText().Trim()))
{
RemoveNodeSafely(lastInsertedParagraph);
}
// Removes empty paragraph placeholder and SDT insert placeholder
RemoveNodeSafely(newParagraph);
RemoveNodeSafely(nodeToInsertBefore);
// Saves merged document
builder.Document.Save("Output.docx");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
/// <summary>
/// Removes node from parent node
/// </summary>
/// <param name="node">Node to be removed</param>
public static void RemoveNodeSafely(Node node)
{
if (node?.ParentNode != null)
{
node.Remove();
}
}
/// <summary>
/// Gets the first child node that matches search criteria
/// </summary>
/// <param name="compositeNode">Composite node</param>
/// <param name="searchCriteria">Search criteria</param>
/// <returns>Structured document tag or null</returns>
public static StructuredDocumentTag GetFirstChild(CompositeNode compositeNode, string searchCriteria)
{
Regex regex = new Regex(searchCriteria);
List<StructuredDocumentTag> allNodes = compositeNode.GetChildNodes(NodeType.StructuredDocumentTag, true)
.Cast<StructuredDocumentTag>().ToList();
return allNodes.FirstOrDefault(it => regex.IsMatch(it.Title));
}
/// <summary>
/// Inserts node before referenced one
/// </summary>
/// <param name="newNode">Node to be inserted</param>
/// <param name="referenceNode">References node</param>
public static void InsertNodeBefore(Node newNode, Node referenceNode)
{
if (referenceNode?.ParentNode != null && newNode != null)
{
// In case when Paragraph has to be inserted into parent node that is also Paragraph, than
// take next parent node - that wll be Body
if (newNode.NodeType == NodeType.Paragraph &&
newNode.NodeType == referenceNode.ParentNode.NodeType)
{
// Insert only in case if parent exists
referenceNode.ParentNode.ParentNode?.InsertBefore(newNode, referenceNode.ParentNode);
}
else
{
referenceNode.ParentNode.InsertBefore(newNode, referenceNode);
}
}
}
}