1

I have a FreeMarker template where I want to specify the output format in order to escape some characters in my XML files. The template example looks as below:

<#ftl output_format="XML">
<#assign field1>
   TestField&1&
</#assign>
<#assign field2>
   <#if field1?trim?length == 0>
      TestField&1&
   <#else>
      TestField&2&
   </#if>
</#assign>
<?xml version="1.0" encoding="UTF-8"?>
<FIELD2>${field2}</FIELD2>

The transformation works fine (except the escaping), unless I put the <#ftl output_format="XML"> directive in my template. After that I get a NonStringException:

freemarker.core.NonStringException: For "?trim" left-hand operand: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to a markup_output (wrapper: f.c.TemplateXMLOutputModel): ==> field1 [in template "Test.ftl" at line 6, column 9]

Basically field1?trim?length does not work, because field1 is not evaluated as a string anymore.

Without the output format directive everything woks as expected.
FreeMarker version I'm using is 2.3.26-incubating.

DimaSan
  • 12,264
  • 11
  • 65
  • 75

2 Answers2

1

You can use the markup_string builtin, which returns the markup stored inside a markup output value as string.

<#ftl output_format="XML">
<#assign field1>
    TestField&1&
</#assign>
<#assign field2>
    <#if field1?markup_string?trim?length == 0>
        TestField&1&
    <#else>
        TestField&2&
    </#if>
</#assign>
<?xml version="1.0" encoding="UTF-8"?>
<FIELD2>${field2}</FIELD2>
obourgain
  • 8,856
  • 6
  • 42
  • 57
0

To prevent this error with XML outputformat you can assign field1 with string value:

<#ftl output_format="XML">
<#assign field1 ="TestField&1&"/>
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • Thank you for the suggestion, but unfortunately it does not work neither. The result of such assignment is `org.xmlunit.XMLUnitException: The entity name must immediately follow the '&' in the entity reference` – DimaSan Feb 23 '21 at 12:53
  • @DimaSan this is XML issue, do you mean to use &? see https://stackoverflow.com/questions/16303779/the-entity-name-must-immediately-follow-the-in-the-entity-reference – Ori Marko Feb 23 '21 at 12:58
  • @DimaSan Does that `XMLUnitException` occur after you did `${field2}`? Then maybe auto escaping is turned off there, which is not recommended. (Or, `XMLUnit` tries to validate the template itself as XML? Although then it would choke on `<#` as well.) – ddekany Mar 11 '21 at 08:12