Insert Quotation Marks in an IF-Then Condition in Word DOCX Document | Mail Merge using C# .NET | Merge Field

I use an if-then condition in a template.

Example:
{ IF { MERGEFIELD LF_TEXT } = “” { MERGEFIELD LF_NAME } { MERGEFIELD LF_TEXT } }

Problem:
If there are spaces or line breaks in the MERGEFIELDS, Aspose.Words does not evaluate the condition correctly. In addition, only the part up to the space or line break is output.

One solution would be to put the individual parts of the condition in single quotes.
Example:
{ IF “{ MERGEFIELD LF_TEXT }” = “” “{ MERGEFIELD LF_NAME }” “{ MERGEFIELD LF_TEXT }” }

However, this would mean that our customers would have to check and adapt all of their templates (hundreds if necessary).

How can I programmatically add the quotation marks before the merge?

@Niebelschutz,

Please ZIP and attach the following resources here for testing:

  • Your simplified input Word document
  • Please also create a standalone simple console application (source code without compilation errors) that helps us to reproduce your current problem on our end and attach it here for testing. Please do not include Aspose.Words DLL/JAR files in it to reduce the file size.

As soon as you get these pieces of information ready, we will start investigation into your scenario and provide you more information. Thanks for your cooperation.

20200507 - IfThenCondition.zip (38.6 KB)

@Niebelschutz,

We have also logged this problem in our issue tracking system. Your ticket number is WORDSNET-20396. We will further look into the details of this problem and will keep you updated on the status of the linked issue. Sorry for the inconvenience.

Have you already looked at the problem?
Our customer urgently needs a solution to his problem.

@Niebelschutz,

We are currently analyzing the issue so please spare us some more time. We will get back to you with some outcome (analysis result, fix or workaround) shortly.

@Niebelschutz,

Regarding WORDSNET-20396, it is to update you that we have completed the work on this issue and concluded to close this issue with “Not a Bug” status. Please see the following analysis details.

We have discovered that Aspose.Words does process white-spaces in the merge field values correctly. Example (see attachment.zip (18.0 KB)):

var document = new Document("mm.docx");
document.MailMerge.Execute(
    new[] { "left", "right", "true", "false" },
    new object[]
    {
        "this is an expression",
        "this is an expression",
        "this is a true argument",
        "this is a false argument"
    });
document.Save("mm Out.docx");

As you can see, the output is totally correct and the white-spaces are preserved. You are experiencing the issues because you are manually inserting nodes into merge fields:

_builder.MoveToMergeField(e.FieldName);
_builder.InsertDocument(rtfDoc, ImportFormatMode.UseDestinationStyles);

This excludes mail merge engine from the process of merge field update and therefore it does not correctly handle white-spaces (breaks).

Also, you can use the following sample code to enclose child merge fields in double quotes to make the IF field keep the white-spaces in the arguments:

public class MergeFieldQuoteEnsurer : DocumentVisitor
{
    public override VisitorAction VisitRun(Run run)
    {
        if (!IsInIfField)
            return VisitorAction.Continue;

        bool isEscaped = false;

        foreach (char c in run.Text)
        {
            switch (c)
            {
                case '\\':
                    isEscaped = !isEscaped;
                    break;
                case '"':
                    if (!isEscaped)
                        mQuoteCount++;
                    break;
            }

            if (c != '\\' && isEscaped)
                isEscaped = false;
        }

        return VisitorAction.Continue;
    }

    public override VisitorAction VisitFieldStart(FieldStart fieldStart)
    {
        switch (fieldStart.FieldType)
        {
            case FieldType.FieldIf:
                mIfCount++;
                // Ideally we need to have a stack of quote counters for each nested IF, but for simplicity just reset it for the outermost.
                if (mIfCount == 1)
                    mQuoteCount = 0;
                break;
            case FieldType.FieldMergeField:
                if (IsInIfField && !IsInQuotes)
                    mFieldsToProcess.Add(fieldStart.GetField());
                break;
        }

        return VisitorAction.Continue;
    }

    public override VisitorAction VisitFieldEnd(FieldEnd fieldEnd)
    {
        switch (fieldEnd.FieldType)
        {
            case FieldType.FieldIf:
                mIfCount--;
                break;
        }

        return VisitorAction.Continue;
    }

    public override VisitorAction VisitDocumentEnd(Document doc)
    {
        InsertQuotes();
        return VisitorAction.Continue;
    }

    private void InsertQuotes()
    {
        foreach (var field in mFieldsToProcess)
        {
            var fieldStart = field.Start;
            var fieldEnd = field.End;

            fieldStart.ParentNode.InsertBefore(new Run(fieldStart.Document, "\""), fieldStart);
            fieldEnd.ParentNode.InsertAfter(new Run(fieldEnd.Document, "\""), fieldEnd);
        }
    }

    private bool IsInIfField
    {
        get { return mIfCount > 0; }
    }

    private bool IsInQuotes
    {
        get { return (mQuoteCount & 1) == 1; }
    }

    private int mIfCount;
    private int mQuoteCount;
    private List<Field> mFieldsToProcess = new List<Field>();
}

Usage:

var quoteEnsurer = new MergeFieldQuoteEnsurer();
doc.Accept(quoteEnsurer);

Hope, this helps.

Thanks a lot. That helped.
Our customers will be relieved that they don’t have to customize hundreds of templates.

Our customer has reported a problem:
In a comparison, e.g. with a number, the evaluation does not work if the mergefield is enclosed in single quotes. (Incidentally, the same problem also occurs when comparing the dates.)

{IF “{MERGEFIELD PRICE}” > 0 {MERGEFIELD PRICE} “free”}

Is it possible to check whether one side (left or right) of the comparison operation is a mergefield or string, so that only in this case is the mergefield set in single quotes?

@Niebelschutz,

Please ZIP and attach a simplified new template Word document and a console application here for testing. We will then start further investigation into this problem and provide you more information.

20200707_MergeFieldQuoteEnsurer.zip (31.5 KB)

Due to the problems with numbers and the fact that the original problem only occurred with strings (RTF), I have adjusted the MergeFieldQuoteEnsurer so that it only puts string-type mergefields in single quotes.
Unfortunately, the customer sometimes already put one side of the condition in single quotes in his templates, which means that the comparison Decimal = “0” or DateTime = “07.07.2020” does not work.
Please test the sample program once with and once without MergeFieldQuoteEnsurer to see the difference.

Is it possible to intervene in evaluating the condition?

@Niebelschutz,

Thanks for the additional information. We tested the scenario and have managed to reproduce the same problem on our end. For the sake of correction, we have logged this problem in our issue tracking system. The ID of this issue is WORDSNET-20745. We will further look into the details of this problem and will keep you updated on the status of the linked issue. We apologize for your inconvenience.

@Niebelschutz,

Regarding WORDSNET-20745, we have completed the work on this issue and concluded to close this issue with “Not a Bug” status. Please check following analysis details.

There are no types in MS Word document. MS Word’s Mail Merge (and Aspose.Words Mail Merge) may evaluate similar expressions w/ and w/o quotes in different ways. But, this is currently an expected behavior. Here is modified template where we just added the second set of fields w/ quotes ( see template modified.zip (11.9 KB)) and populated outputs by Aspose.Words (see AW.zip (10.1 KB)) and MS Word (see MS.zip (11.3 KB)).

We may consider to expose extension point for condition evaluation. We have logged a new issue with ID WORDSNET-20913 to investigate the problem of the extension point implementation. We will keep you posted here on any further updates.