Free Support Forum - aspose.com

Conditional text in mailmerge behaving oddly following Aspose update

Hi,
I’m using Aspose words for java, and I have an example mailmerge document making use of conditional text which is behaving incorrectly after a recent Aspose upgrade. This example works as I expect in Aspose Words 18.7, but has changed somewhere between then and Aspose Words 19.9 (I also tried the latest versions 19.10 and 19.11).

I’ve attached a minimal test case with an application, the template Word document and the expected and actual results. Repeating here for visibility:

My template looks like this:

Value of FIELD1 field: "{ MERGEFIELD "FIELD1" }"
Value of FIELD2 field: "{ MERGEFIELD "FIELD2" }"

Example 1.	
{IF MERGEFIELD "FIELD1" } <> "" "Text text" "empty" }

Example 2.	
{IF MERGEFIELD "FIELD1" } <> "" "{ MERGEFIELD "FIELD2" }" "empty" }

Example 3.	
{IF MERGEFIELD "FIELD1" } <> "" "Text { MERGEFIELD "FIELD2" } text" "empty" }

Example 4.	
{IF MERGEFIELD "FIELD1" } <> "" "Text { IF 1 = 1 "Yes and { MERGEFIELD "FIELD2" }." "No" } text" "empty" }

I’m running it with a blank value for FIELD1 and the value “ABC” for FIELD2. What I expect is that all 4 of the example fields resolve to “empty”, because FIELD1 is blank. This makes sense and is also the behaviour that I see when performing the mailmerge MS Word.

Expected result and result using Word or Aspose 18.7:

Value of FIELD1 field: ""
Value of FIELD2 field: "ABC"

Example 1.	
empty

Example 2.	
empty

Example 3.	
empty

Example 4.	
empty

The attached example application that runs this same mailmerge using the latest version of Aspose. It uses the methods MailMerge.execute() followed by Field.unlink() using a document visitor to unlink all of the fields. What I actually see when running this mailmerge with the application is that examples 2 and 3 both somehow resolve to “FIELD2”, which seems very wrong.

Actual result from Aspose 19.10:

Value of FIELD1 field: ""
Value of FIELD2 field: "ABC"

Example 1.	
empty

Example 2.	
FIELD2

Example 3.	
FIELD2

Example 4.	
empty

If I put a filter on the document vistor to only unlink the conditional IF fields and not the mergefields, then it fixes examples 2 and 3 but breaks example 4. (this is what my real application actually does currently)

I’ve discovered that there is another workaround which is that if I add this line:
mailMerge.setUnconditionalMergeFieldsAndRegions(true);
then this fixes all 4 of my examples. However I’m reluctant to use this in my application after reading the documentation:

https://docs.aspose.com/display/wordsjava/How+to+Execute+Mail+Merge#HowtoExecuteMailMerge-SwitchBetweenOldandNewMailMergeBehaviors
and section “Option to Choose Between Old and New Mail Merge Behaviors Added” near the end of here: https://docs.aspose.com/display/wordsjava/Aspose.Words+for+Java+18.9+Release+Notes

The documents seem to say that setUnconditionalMergeFieldsAndRegions(true) reverts to an older Aspose behaviour that is inconsistent with MS Word, but in my case I’m seeing the opposite: I want the behaviour to be consistent with Word and in my case using this option seems to make it more consistent. Also I understand this option was added in response to the problem WORDSNET-17313 which was raised in Aspose 18.7 (and allows the behaviour to be reverted to some version before that), whereas my example works as expected in Aspose 18.7, so I don’t think my problem is the same as the one this option was meant to solve.

I’d appreciate any help that could be offered with this problem.

aspose-testcase.zip (104.7 KB)

@nedsmith

You are facing this behavior due to usage of FieldUnlinker with mail merge. In your case, we suggest you please use mail merge CleanupOptions as shown below. In this case, you do not need to call Document.Accept for FieldUnlinker class.

mailMerge.setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS);
mailMerge.execute(fieldNames, fieldValues);

If you want to use FieldUnlinker, you need to modify the code according to your requirement. E.g. please check the following code.

public int visitFieldEnd(FieldEnd fieldEnd) throws Exception {
    Field field = fieldEnd.getField();
    //if (field.getType() == FieldType.FIELD_IF) {  // fixes examples 2 and 3 but breaks example 4
    field.update();

    if(field.getType() == FieldType.FIELD_MERGE_FIELD)
        field.remove();
    else
        field.unlink();
    //}
    return super.visitFieldEnd(fieldEnd);
}

Hi @tahir.manzoor, many thanks for the quick response, that is very helpful.

To clarify, our business requirement is to resolve the mailmerge completely, so the end result should be a plain document that doesn’t contain any fields. For this reason I think we have to use the unlink method in some way - using the cleanup options by themselves always seem to leave fields in the result. We have used the options REMOVE_STATIC_FIELDS and REMOVE_CONTAINING_FIELDS in the past and had trouble with “Bookmark not found” errors, although we haven’t used the REMOVE_UNUSED_FIELDS option before.

The approach of removing the merge fields and unlinking all the other fields seems to work in my test case and looks as though it could work in our more complex real-world examples, so we’ll explore using this approach as the way forward for us.

I’m curious as to why the mailmerge fields seem to behave differently to the other field types? - intuitively I’d expect that field.remove() would delete the mergefield entirely and also delete any value from the data that has been merged. It looks like what it actually does is leave the merged value as plain text, which is what I wanted and what I was expecting to happen from calling field.unlink(). Is there any information available that could aid my understanding of this?

@nedsmith

Please note that Field.Remove method completely removes the field from the document and Field.Unlink method replaces the field with its most recent result.

We did not face the shared issue while using the latest version of Aspose.Words for Java 19.11 with your code example.

If you still face problem, please ZIP and attach the document for which you are facing this issue and code example here for testing. We will investigate this issue further and provide you more information on it.

Thanks again Tahir, after reading this I looked at it again and clearly my previous comment wasn’t quite right, now I think I can answer my own question. Looking at the intermediate result between the mailmerge and the unlink was useful to work out what’s going on.

So merge fields that are actually used effectively get “unlinked” during the merge and turn into plain text. Whereas unused merge fields (those in false conditional blocks) get left as merge fields without any value which is what causes the problems - they always seem to give strange results regardless of whether you subsequently try to unlink them or not. So the only way to fix the problem is to remove those mergefields entirely, which does delete them but it doesn’t matter because unlinking the IF fields removes those sections anyway. Still not quite sure how that explains the original results I got, but it means the code changes make sense to me now.

@nedsmith

Your understanding about performing mail merge, removing fields and unlink the fields is correct. You are performing mail merge, remove and unlink fields.

When you perform mail merge, it replaces mail merges fields with their values. At this step, you can use MailMerge.UnconditionalMergeFieldsAndRegions property to switch between new and old behavior of mail merge engine. After this step, you may have unused mail merge fields in IF field.

Second step is to remove unused mail merge fields. At second step, if there are unused merge fields; you can remove them by using Field.Remove method or by using mail merge cleanup option MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS as suggested in my previous post.

Third step is to unlink the field. At this step, there may or may not be mail merge fields in the IF field. In both cases, you will get the same result when you unlink the IF field.

Hope this answers your query. Please let us know if you have any more queries.