Template engines for Apache Groovy including SimpleTemplateEngine, StreamingTemplateEngine, XmlTemplateEngine, and MarkupTemplateEngine
—
The XmlTemplateEngine provides specialized template processing for XML documents with <gsp:scriptlet> and <gsp:expression> support. It includes automatic XML escaping, proper indentation, and namespace handling for generating well-formed XML output.
Creates XML templates with automatic escaping, indentation, and GSP tag support.
/**
* Template engine for XML templates with gsp:scriptlet and gsp:expression support.
* Provides automatic XML escaping, indentation, and namespace handling.
*/
public class XmlTemplateEngine extends TemplateEngine {
public static final String DEFAULT_INDENTATION = " ";
/**
* Creates a new XmlTemplateEngine with default settings
* @throws SAXException if XML parser configuration fails
* @throws ParserConfigurationException if XML parser cannot be configured
*/
public XmlTemplateEngine() throws SAXException, ParserConfigurationException;
/**
* Creates a new XmlTemplateEngine with custom indentation and validation
* @param indentation string used for indenting XML output
* @param validating true to enable XML validation during parsing
* @throws SAXException if XML parser configuration fails
* @throws ParserConfigurationException if XML parser cannot be configured
*/
public XmlTemplateEngine(String indentation, boolean validating) throws SAXException, ParserConfigurationException;
/**
* Creates a new XmlTemplateEngine with custom XML parser and class loader
* @param xmlParser XmlParser instance for parsing templates
* @param parentLoader ClassLoader for template compilation
*/
public XmlTemplateEngine(XmlParser xmlParser, ClassLoader parentLoader);
/**
* Creates a new XmlTemplateEngine with custom XML parser and Groovy shell
* @param xmlParser XmlParser instance for parsing templates
* @param groovyShell GroovyShell for script execution
*/
public XmlTemplateEngine(XmlParser xmlParser, GroovyShell groovyShell);
/**
* Get the current indentation string
* @return indentation string used for XML formatting
*/
public String getIndentation();
/**
* Set the indentation string for XML output
* @param indentation string to use for indenting (null defaults to DEFAULT_INDENTATION)
*/
public void setIndentation(String indentation);
/**
* Set a closure to configure the XML printer
* @param configurePrinter closure that receives the printer as parameter
*/
public void setConfigurePrinter(Closure configurePrinter);
}Usage Examples:
import groovy.text.XmlTemplateEngine;
import groovy.text.Template;
import groovy.xml.XmlParser;
import java.util.Map;
import java.util.HashMap;
// Create XML template engine with default settings
XmlTemplateEngine engine = new XmlTemplateEngine();
// XML template with GSP tags and variable substitution
String xmlTemplate = """
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp' xmlns:foo='baz' type='letter'>
<gsp:scriptlet>def greeting = "${salutation}est"</gsp:scriptlet>
<gsp:expression>greeting</gsp:expression>
<foo:to>$firstname "$nickname" $lastname</foo:to>
<message>How are you today?</message>
</document>
""";
Template template = engine.createTemplate(xmlTemplate);
Map<String, Object> binding = new HashMap<>();
binding.put("firstname", "Jochen");
binding.put("lastname", "Theodorou");
binding.put("nickname", "blackdrag");
binding.put("salutation", "Dear");
String result = template.make(binding).toString();
// Output will be properly indented XML with gsp namespace removedXmlTemplateEngine supports special GSP (Groovy Server Pages) tags for embedding logic in XML:
Use <gsp:scriptlet> for executing Groovy code:
<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
<gsp:scriptlet>
def total = 0
items.each { item ->
total += item.price
}
</gsp:scriptlet>
<total>${total}</total>
</document>Use <gsp:expression> for outputting expression results:
<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
<timestamp>
<gsp:expression>new Date().format('yyyy-MM-dd HH:mm:ss')</gsp:expression>
</timestamp>
<userCount>
<gsp:expression>users.size()</gsp:expression>
</userCount>
</document>XmlTemplateEngine supports GString-style variable substitution with automatic XML escaping:
String template = """
<user>
<name>$user.name</name>
<email>${user.email}</email>
<bio>$user.bio</bio> <!-- Automatically XML-escaped -->
</user>
""";
Map<String, Object> binding = new HashMap<>();
Map<String, String> user = new HashMap<>();
user.put("name", "John Doe");
user.put("email", "john@example.com");
user.put("bio", "Software developer with <10 years experience & \"passion\" for code");
binding.put("user", user);
// Output will have proper XML escaping:
// <bio>Software developer with <10 years experience & "passion" for code</bio>Special XML characters are automatically escaped:
// Input template
String template = """
<message>
$content
</message>
""";
Map<String, Object> binding = new HashMap<>();
binding.put("content", "Price: $5 < $10 & \"Special\" offer");
// Output will be properly escaped:
// <message>
// Price: $5 < $10 & "Special" offer
// </message>XML output is automatically indented for readability:
XmlTemplateEngine engine = new XmlTemplateEngine();
// Custom indentation
XmlTemplateEngine customEngine = new XmlTemplateEngine(" ", false); // 4 spaces
// Configure indentation programmatically
engine.setIndentation("\t"); // Use tabsGSP namespace is removed from output, other namespaces are preserved:
<!-- Input template -->
<root xmlns:gsp='http://groovy.codehaus.org/2005/gsp' xmlns:custom='http://example.com'>
<gsp:scriptlet>def value = "test"</gsp:scriptlet>
<custom:element>$value</custom:element>
</root>
<!-- Output (gsp namespace removed, custom namespace preserved) -->
<root>
<custom:element xmlns:custom='http://example.com'>test</custom:element>
</root>Configure indentation string for XML output:
// Use tabs for indentation
XmlTemplateEngine engine = new XmlTemplateEngine();
engine.setIndentation("\t");
// Use 4 spaces
engine.setIndentation(" ");
// No indentation (compact output)
engine.setIndentation("");Use a closure to configure the XML printer:
XmlTemplateEngine engine = new XmlTemplateEngine();
engine.setConfigurePrinter(new Closure(null) {
public void call(Object printer) {
// Configure printer properties
// printer.preserveWhitespace = true;
}
});Enable XML validation during template parsing:
// Enable validation
XmlTemplateEngine validatingEngine = new XmlTemplateEngine(" ", true);Use a custom XML parser with specific configuration:
import groovy.xml.XmlParser;
XmlParser customParser = new XmlParser();
customParser.setTrimWhitespace(false);
customParser.setNamespaceAware(true);
XmlTemplateEngine engine = new XmlTemplateEngine(customParser, getClass().getClassLoader());Generate complex XML structures with conditional logic:
String template = """
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
<gsp:scriptlet>
def categories = products.groupBy { it.category }
</gsp:scriptlet>
<gsp:expression>
categories.each { category, items ->
out << "<category name='${category}'>"
items.each { product ->
out << "<product id='${product.id}' price='${product.price}'>${product.name}</product>"
}
out << "</category>"
}
</gsp:expression>
<summary>
<totalProducts><gsp:expression>products.size()</gsp:expression></totalProducts>
<totalCategories><gsp:expression>categories.size()</gsp:expression></totalCategories>
</summary>
</catalog>
""";XmlTemplateEngine can be used with servlet containers for generating XML responses:
<servlet>
<servlet-name>XmlTemplate</servlet-name>
<servlet-class>groovy.servlet.TemplateServlet</servlet-class>
<init-param>
<param-name>template.engine</param-name>
<param-value>groovy.text.XmlTemplateEngine</param-value>
</init-param>
</servlet>XmlTemplateEngine provides detailed error handling for XML-specific issues:
try {
XmlTemplateEngine engine = new XmlTemplateEngine();
Template template = engine.createTemplate(xmlTemplate);
String result = template.make(binding).toString();
} catch (SAXException e) {
// XML parsing error in template source
System.err.println("XML parsing error: " + e.getMessage());
} catch (ParserConfigurationException e) {
// XML parser configuration issue
System.err.println("Parser configuration error: " + e.getMessage());
} catch (RuntimeException e) {
if (e.getMessage().contains("Parsing XML source failed")) {
// XML structure error
System.err.println("Invalid XML structure: " + e.getMessage());
} else {
throw e;
}
} catch (IOException e) {
// I/O error reading template
System.err.println("I/O error: " + e.getMessage());
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-groovy--groovy-templates