How to remove whitespaces from a conditional statement

We are using Aspose.Words in our application as a third party library. Our application is written in OpenEdge and is able to do the mailmerge. However, we have an issue if our word template contains a conditional statement.
For example, we have this conditional statement (see below). In the statement, there’s tab and carriage return. If one of the field in the condition is blank, we want
to remove the whitespaces (tabs, carriage return) so that there’s no blank lines being generated.

{ IF {MERGEFIELD LineType } = “Header” “{ IF { MERGEFIELD ManagerCode } <> “” “Manager:” “” 
} <Tab> { MERGEFIELD ManagerCode } <Tab> {MERGEFIELD ManagerName } <CR> 
{ IF { MERGEFIELD AgentCode } <> “” “Agent:” “” } <Tab> { MERGEFIELD AgentCode } <Tab> 
{MERGEFIELD AgentName } <CR>
{ IF { MERGEFIELD ClientCode } <> “” “Client:” “” } <Tab> { MERGEFIELD ClientCode } <Tab> 
{MERGEFIELD ClientName } <CR>
{ IF { MERGEFIELD EstateCode } <> “” “Estate:” “” } <Tab> { MERGEFIELD EstateCode } <Tab> 
{MERGEFIELD EstateAddress } <CR>
{ IF { MERGEFIELD PropertyCode } <> “” “Property:” “” } <Tab> { MERGEFIELD PropertyCode } 
<Tab> {MERGEFIELD PropertyAddress } <CR>
{ IF { MERGEFIELD TenantCode } <> “” “Tenant:” “” } <Tab> { MERGEFIELD TenantCode } <Tab> 
{MERGEFIELD TenantName } <Tab> {MERGEFIELD TenantContact} <CR>
{ IF { MERGEFIELD LeaseCode } <> “” “Tenancy:” “” } <Tab> { MERGEFIELD LeaseCode } <Tab> 
{MERGEFIELD LeaseAddress } <CR>
{ IF { MERGEFIELD InvStatusCode } <> “” “Inv Status:” “” } <Tab> { MERGEFIELD InvStatusCode } 
<Tab> {MERGEFIELD InvStatusDescription } <CR>
” “”}

Currently, what’s happening is, for example, estatecode, tenantcode and leasecode are blank, this is what is being generated, a blank line between Client and Property, and blank lines between Property and Inv Status:

Agent: Agent001 Agent Name
Client: Client001 Client Name

Property: Property001 Property Address

Inv Status: 001 Inv Status Description

What we would want is:

Agent: Agent001 Agent Name
Client: Client001 Client Name
Property: Property001 Property Address
Inv Status: 001 Inv Status Description

How can this be achieved in Aspose?

@cmendoza You can use MailMerge.CleanupOptions to get the desired output. For example see the following code, template and output document:

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

string[] fieldNames = new string[] { "ManagerCode", "ManagerName", "AgentCode", "AgentName", "ClientCode", "ClientName", "EstateCode", "EstateAddress", "PropertyCode", "PropertyAddress", "TenantCode", "TenantName", "TenantContact", "LeaseCode", "LeaseAddress", "InvStatusCode", "InvStatusDescription" };
string[] fieldValues = new string[] { "", "", "AgentCode", "AgentName", "", "", "EstateCode", "EstateAddress", "PropertyCode", "PropertyAddress", "", "", "", "LeaseCode", "LeaseAddress", "InvStatusCode", "InvStatusDescription" };

doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs | MailMergeCleanupOptions.RemoveContainingFields;
doc.MailMerge.Execute(fieldNames, fieldValues);

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

in.docx (13.9 KB)
out.docx (10.0 KB)

Hi Alexey,
Thank you very much for your reply. The conditional statement in my template is one big statement. I have attached my sample template, data source, and header source to show you how the conditional statement is constructed. sample-template.7z (17.8 KB)

I’ve applied your suggested code to my Openedge code, but the whitespaces are not being removed. By the way, I used ExecuteWithRegions with a dataset parameter to execute the mail merge because my template is a Catalog. The sample contents of my dataset is also included in the attached file
Here is part of my sample code, this is written in OpenEdge:

DEFINE PUBLIC PROPERTY DocModel1  AS Aspose.Words.Document  NO-UNDO PUBLIC GET.  PRIVATE SET.
DEFINE PRIVATE PROPERTY DataSet1  AS System.Data.DataSet  NO-UNDO  GET.  SET.
DEFINE VARIABLE rEnum   AS System.Enum NO-UNDO.

THIS-OBJECT:DocModel1 = NEW Aspose.Words.Document("c:\temp\tlout.docx").

DataSet1 = NEW DataSet("CatalogMerge").
    
// these options operate on ranges in the finished document that have ended up blank
rEnum = MailMergeCleanupOptions:RemoveEmptyParagraphs.             
rEnum = EnumHelper:Or(rEnum, MailMergeCleanupOptions:RemoveContainingFields).     

// rEnum = EnumHelper:Or(rEnum, MailMergeCleanupOptions:RemoveUnusedFields).     

// ... and finally set the selected options on the mail merge object 
THIS-OBJECT:DocModel1:MailMerge:CleanupOptions = CAST(rEnum, MailMergeCleanupOptions).                   

THIS-OBJECT:DocModel1:MailMerge:ExecuteWithRegions(DataSet1).

Thank you very much.

@cmendoza Thank you for additional information. I have managed to reproduce the problem with nested IF fields and cleanup options. For a sake of correction the issue has been logged as WORDSNET-23511. We will keep you informed and let you know once it is resolved.

I do not see TableStart and TableEnd merge fields in your template. I suspect you are inserting them dynamically. Anyways the problem is reproducible with simple mail merge too using the following code:

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

string[] fieldNames = new string[] { "LineType", "ManagerCode", "ManagerName", "AgentCode", "AgentName", "ClientCode", "ClientName", "EstateCode", "EstateAddress", "PropertyCode", "PropertyAddress", "TenantCode", "TenantName", "TenantContact", "TenantPhone", "InvStatusCode", "InvStatusDescription", "BlankField", "LeaseCode", "LeaseAddress", "LeaseDetail", "PageBreak" };
string[] fieldValues = new string[] { "Header", "", "", "AgentCode", "AgentName", "", "", "EstateCode", "EstateAddress", "PropertyCode", "PropertyAddress", "TenantCode", "TenantName", "TenantContact", "TenantPhone", "InvStatusCode", "InvStatusDescription", "BlankField", "LeaseCode", "LeaseAddress", "LeaseDetail", "PageBreak" };

doc.MailMerge.CleanupOptions = MailMergeCleanupOptions.RemoveEmptyParagraphs |
    MailMergeCleanupOptions.RemoveContainingFields;
doc.MailMerge.Execute(fieldNames, fieldValues);

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

As a temporary workaround you can remove empty paragraphs by postprocessing your document. For example see the following code, which should be run after execution mail merge:

// Get all paragraphs.
NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
foreach (Paragraph p in paragraphs)
{
    // Remove paragraphs with no visible text.
    if (string.IsNullOrEmpty(p.ToString(SaveFormat.Text).Trim()))
        p.Remove();
}

Hi Alexey,

Thanks for providing a workaround. I’ve tried it and it correctly removes the paragraphs with no visible text. However, when I tried using it on a different template with nested IF fields to display underlines, it is also removing the underlines.

I have attached my sample template, data source, and header source to show you how the conditional statement is constructed. Also attached is the sample document I generated before applying the workaround and after applying the workaround. sample-template.7z (52.8 KB)

Any assistance will be much appreciated.

Thank you very much.

@cmendoza The line in your template is not underline, it is shape. You can modify the workaround code line this, to preserve the line:

// Get all paragraphs.
NodeCollection paragraphs = doc.GetChildNodes(NodeType.Paragraph, true);
foreach (Paragraph p in paragraphs)
{
    // Remove paragraphs with no visible text.
    if (string.IsNullOrEmpty(p.ToString(SaveFormat.Text).Trim()) && p.GetChildNodes(NodeType.Shape, true).Count == 0)
        p.Remove();
}

Thanks Alexey, I will use the workaround for now.

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