CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-groovy--groovy-templates

Template engines for Apache Groovy including SimpleTemplateEngine, StreamingTemplateEngine, XmlTemplateEngine, and MarkupTemplateEngine

Pending
Overview
Eval results
Files

xml-templates.mddocs/

XML Templates

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.

Capabilities

XML Template Engine Class

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 removed

GSP Tag Support

XmlTemplateEngine supports special GSP (Groovy Server Pages) tags for embedding logic in XML:

GSP Scriptlet Tag

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>

GSP Expression Tag

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>

Variable Substitution

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 &lt;10 years experience &amp; &quot;passion&quot; for code</bio>

XML Features

Automatic XML Escaping

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 &lt; $10 &amp; &quot;Special&quot; offer  
// </message>

Automatic Indentation

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 tabs

Namespace Handling

GSP 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>

Configuration Options

Custom Indentation

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("");

Printer Configuration

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;
    }
});

Validation

Enable XML validation during template parsing:

// Enable validation
XmlTemplateEngine validatingEngine = new XmlTemplateEngine("  ", true);

Advanced Usage

Custom XML Parser

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());

Complex XML Generation

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>
""";

Web Integration

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>

Error Handling

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());
}

Best Practices

  1. Namespace Declaration: Always declare the GSP namespace in your XML templates
  2. Escaping: Let the engine handle XML escaping automatically - don't manually escape
  3. Indentation: Use consistent indentation settings across your application
  4. Validation: Enable validation during development to catch XML structure issues
  5. Comments: XML comments and processing instructions are removed from output
  6. Performance: Consider caching compiled templates for frequently used XML structures

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-groovy--groovy-templates

docs

gstring-templates.md

index.md

markup-templates.md

simple-templates.md

streaming-templates.md

xml-templates.md

tile.json