or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

basic-template-engines.mdindex.mdmarkup-template-engine.mdstreaming-template-engine.mdxml-template-engine.md

xml-template-engine.mddocs/

0

# XML Template Engine

1

2

The XmlTemplateEngine is designed for scenarios where both the template source and expected output are XML. It provides special GSP (Groovy Server Pages) tags for embedding code and expressions while maintaining well-formed XML structure.

3

4

## API

5

6

```java { .api }

7

class XmlTemplateEngine extends TemplateEngine {

8

XmlTemplateEngine() throws SAXException, ParserConfigurationException;

9

XmlTemplateEngine(String indentation, boolean validating) throws SAXException, ParserConfigurationException;

10

XmlTemplateEngine(XmlParser xmlParser, ClassLoader parentLoader);

11

XmlTemplateEngine(XmlParser xmlParser, GroovyShell groovyShell);

12

13

Template createTemplate(Reader reader) throws CompilationFailedException, ClassNotFoundException, IOException;

14

void setIndentation(String indentation);

15

String getIndentation();

16

void setConfigurePrinter(Closure configurePrinter);

17

18

// Constants

19

static final String DEFAULT_INDENTATION = " ";

20

}

21

```

22

23

## Template Syntax

24

25

### GSP Tags

26

27

- **`<gsp:scriptlet>...</gsp:scriptlet>`** - Execute Groovy code fragments

28

- **`<gsp:expression>...</gsp:expression>`** - Output expression results

29

- **GString expressions**: `${...}` and `$variable` - Variable interpolation within text content

30

31

### XML Processing Features

32

33

- **Comments and processing instructions removed** during processing

34

- **Special XML characters** (`<`, `>`, `"`, `'`) are automatically escaped

35

- **Output is automatically indented** using standard XML pretty printing

36

- **Namespace definitions for `gsp:` tags are removed** from output

37

- **Other namespace definitions are preserved** but may change position

38

39

## Usage Examples

40

41

### Basic XML Template

42

43

```java

44

import groovy.text.XmlTemplateEngine;

45

import groovy.text.Template;

46

import java.util.HashMap;

47

import java.util.Map;

48

49

XmlTemplateEngine engine = new XmlTemplateEngine();

50

51

String templateText = """

52

<?xml version="1.0" encoding="UTF-8"?>

53

<document xmlns:gsp='http://groovy.codehaus.org/2005/gsp' xmlns:foo='baz' type='letter'>

54

<gsp:scriptlet>def greeting = "${salutation}est"</gsp:scriptlet>

55

<gsp:expression>greeting</gsp:expression>

56

<foo:to>$firstname "$nickname" $lastname</foo:to>

57

How are you today?

58

</document>

59

""";

60

61

Template template = engine.createTemplate(templateText);

62

63

Map<String, Object> binding = new HashMap<>();

64

binding.put("firstname", "Jochen");

65

binding.put("lastname", "Theodorou");

66

binding.put("nickname", "blackdrag");

67

binding.put("salutation", "Dear");

68

69

String result = template.make(binding).toString();

70

```

71

72

Output:

73

```xml

74

<document type='letter'>

75

Dearest

76

<foo:to xmlns:foo='baz'>

77

Jochen "blackdrag" Theodorou

78

</foo:to>

79

How are you today?

80

</document>

81

```

82

83

### Custom Indentation

84

85

```java

86

// Custom indentation (4 spaces instead of default 2)

87

XmlTemplateEngine engine = new XmlTemplateEngine(" ", false);

88

89

// Or set indentation after creation

90

engine.setIndentation("\t"); // Use tabs

91

```

92

93

### Validating Parser

94

95

```java

96

// Enable XML validation during parsing

97

XmlTemplateEngine engine = new XmlTemplateEngine(" ", true);

98

```

99

100

### Custom XML Parser and Class Loader

101

102

```java

103

import groovy.xml.XmlParser;

104

105

XmlParser customParser = new XmlParser();

106

customParser.setTrimWhitespace(false); // Preserve whitespace

107

ClassLoader customLoader = MyClass.class.getClassLoader();

108

109

XmlTemplateEngine engine = new XmlTemplateEngine(customParser, customLoader);

110

```

111

112

### Custom Printer Configuration

113

114

```java

115

XmlTemplateEngine engine = new XmlTemplateEngine();

116

117

// Configure the XML printer

118

engine.setConfigurePrinter(new Closure<Void>(this) {

119

public void doCall(Object printer) {

120

// printer is a GspPrinter instance

121

((groovy.text.XmlTemplateEngine.GspPrinter) printer).setPreserveWhitespace(true);

122

}

123

});

124

```

125

126

### Complex Template with Conditional Logic

127

128

```java

129

String templateText = """

130

<?xml version="1.0" encoding="UTF-8"?>

131

<report xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>

132

<header>

133

<title>$reportTitle</title>

134

<date><gsp:expression>new Date().format('yyyy-MM-dd')</gsp:expression></date>

135

</header>

136

<body>

137

<gsp:scriptlet>

138

def totalAmount = items.sum { it.price * it.quantity }

139

</gsp:scriptlet>

140

141

<items>

142

<gsp:scriptlet>

143

items.each { item ->

144

out.println("<item>")

145

out.println(" <name>${item.name}</name>")

146

out.println(" <price>${item.price}</price>")

147

out.println(" <quantity>${item.quantity}</quantity>")

148

out.println("</item>")

149

}

150

</gsp:scriptlet>

151

</items>

152

153

<summary>

154

<total>$totalAmount</total>

155

<gsp:scriptlet>

156

if (totalAmount > 1000) {

157

out.println("<discount>10%</discount>")

158

}

159

</gsp:scriptlet>

160

</summary>

161

</body>

162

</report>

163

""";

164

165

Map<String, Object> binding = new HashMap<>();

166

binding.put("reportTitle", "Sales Report");

167

binding.put("items", Arrays.asList(

168

Map.of("name", "Widget A", "price", 25.50, "quantity", 10),

169

Map.of("name", "Widget B", "price", 15.75, "quantity", 5)

170

));

171

```

172

173

### Error Handling

174

175

```java

176

import org.xml.sax.SAXException;

177

import javax.xml.parsers.ParserConfigurationException;

178

179

try {

180

XmlTemplateEngine engine = new XmlTemplateEngine();

181

Template template = engine.createTemplate(xmlTemplateSource);

182

String result = template.make(binding).toString();

183

} catch (SAXException e) {

184

// XML parsing error

185

System.err.println("XML parsing failed: " + e.getMessage());

186

} catch (ParserConfigurationException e) {

187

// XML parser configuration error

188

System.err.println("XML parser configuration error: " + e.getMessage());

189

} catch (RuntimeException e) {

190

// Unsupported GSP tag or other runtime error

191

if (e.getMessage().contains("Unsupported 'gsp:' tag")) {

192

System.err.println("Invalid GSP tag: " + e.getMessage());

193

} else {

194

throw e;

195

}

196

}

197

```

198

199

## Servlet Integration

200

201

The XmlTemplateEngine can be used with TemplateServlet for web applications:

202

203

```xml

204

<!-- web.xml -->

205

<servlet>

206

<servlet-name>XmlTemplate</servlet-name>

207

<servlet-class>groovy.servlet.TemplateServlet</servlet-class>

208

<init-param>

209

<param-name>template.engine</param-name>

210

<param-value>groovy.text.XmlTemplateEngine</param-value>

211

</init-param>

212

</servlet>

213

```

214

215

## Best Practices

216

217

### Template Structure

218

219

1. **Always include XML declaration** for proper encoding handling

220

2. **Use proper namespace declaration** for GSP tags: `xmlns:gsp='http://groovy.codehaus.org/2005/gsp'`

221

3. **Keep GSP tags minimal** - complex logic should be in scriptlets

222

4. **Use expressions for simple output** and scriptlets for complex logic

223

224

### Performance Considerations

225

226

1. **Reuse engine instances** when possible

227

2. **Cache compiled templates** for frequently used templates

228

3. **Use appropriate indentation settings** - simpler indentation is faster

229

4. **Disable validation** for templates you trust to improve performance

230

231

### XML Escaping

232

233

The engine automatically escapes special XML characters in text content, but not within GString expressions. If you need to output literal XML characters within expressions, handle escaping manually:

234

235

```java

236

String templateText = """

237

<message>

238

<content>User said: ${userInput}</content> <!-- Automatically escaped -->

239

<raw><gsp:expression>groovy.xml.XmlUtil.escapeXml(rawContent)</gsp:expression></raw> <!-- Manual escaping -->

240

</message>

241

""";

242

```