I have a template that produces XML. Something like:
<items>
<item th:each="itemEntry: ${rs1}">
<name th:text="${itemEntry.value['ITEM_NAME']}"></name>
</item>
</items>
What would I have to do to wrap the text of element name in CDATA, so that the result would be:
<items>
<item>
<name><![CDATA[My text]]></name>
</item>
</items>
At the end it was quite simple. I had to create my own dialect:
public class KovicaDialect extends AbstractDialect implements IExpressionObjectDialect {
private static final XMLExpressionObjectFactory xmlExpressionObjectFactory = new XMLExpressionObjectFactory();
public KovicaDialect() {
super("kovica");
}
@Override
public IExpressionObjectFactory getExpressionObjectFactory() {
return xmlExpressionObjectFactory;
}
}
The expression object factory looks like this:
public class XMLExpressionObjectFactory implements IExpressionObjectFactory {
private static final String EXPRESSION_OBJECT_PREFIX = "xml";
private static final Set<String> EXPRESSION_OBJECT_NAMES = Collections.unmodifiableSet(new HashSet(Arrays.asList(EXPRESSION_OBJECT_PREFIX)));
@Override
public Set<String> getAllExpressionObjectNames() {
return EXPRESSION_OBJECT_NAMES;
}
@Override
public Object buildObject(IExpressionContext context, String expressionObjectName) {
if (expressionObjectName.equals(EXPRESSION_OBJECT_PREFIX) == true) {
return new XMLUtils();
}
return null;
}
@Override
public boolean isCacheable(String expressionObjectName) {
return true;
}
}
And the util class:
public class XMLUtils {
public String cdata(String str) {
String returnString = null;
if (str != null) {
returnString = "<![CDATA[" + str + "]]>";
}
return returnString;
}
}
You have to set this dialect:
org.thymeleaf.TemplateEngine templateEngine = new org.thymeleaf.TemplateEngine();
templateEngine.addDialect(new KovicaDialect());
then you can use it like this (it has to be an th:utext
):
<name th:utext="${#xml.cdata(itemEntry.value['ITEM_NAMESMALL'])}"></name>