or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dom-processing.mdindex.mdnamespace-support.mdxml-generation.mdxml-parsing.mdxml-utilities.md

xml-generation.mddocs/

0

# XML Generation

1

2

Comprehensive XML building capabilities including markup builders for formatted output, DOM builders for W3C DOM integration, and streaming builders for memory-efficient large document generation.

3

4

## Capabilities

5

6

### MarkupBuilder

7

8

A powerful builder for creating XML and HTML markup with sophisticated formatting options and helper utilities. Extends Groovy's BuilderSupport to provide a DSL approach to XML generation.

9

10

```groovy { .api }

11

/**

12

* Default constructor writing to System.out

13

*/

14

MarkupBuilder()

15

16

/**

17

* Constructor with PrintWriter output

18

* @param pw - PrintWriter for output

19

*/

20

MarkupBuilder(PrintWriter pw)

21

22

/**

23

* Constructor with Writer output

24

* @param writer - Writer for output

25

*/

26

MarkupBuilder(Writer writer)

27

28

/**

29

* Constructor with IndentPrinter for formatted output

30

* @param out - IndentPrinter for formatted output

31

*/

32

MarkupBuilder(IndentPrinter out)

33

```

34

35

#### Configuration Methods

36

37

```groovy { .api }

38

/**

39

* Control quote style for attributes

40

* @param useDoubleQuotes - true for double quotes, false for single

41

*/

42

void setDoubleQuotes(boolean useDoubleQuotes)

43

boolean getDoubleQuotes()

44

45

/**

46

* Control handling of null attribute values

47

* @param omitNullAttributes - true to omit null valued attributes

48

*/

49

void setOmitNullAttributes(boolean omitNullAttributes)

50

boolean isOmitNullAttributes()

51

52

/**

53

* Control handling of empty attribute values

54

* @param omitEmptyAttributes - true to omit empty string attributes

55

*/

56

void setOmitEmptyAttributes(boolean omitEmptyAttributes)

57

boolean isOmitEmptyAttributes()

58

59

/**

60

* Control empty element formatting

61

* @param expandEmptyElements - true to expand empty elements with closing tags

62

*/

63

void setExpandEmptyElements(boolean expandEmptyElements)

64

boolean isExpandEmptyElements()

65

66

/**

67

* Control attribute value escaping

68

* @param escapeAttributes - true to escape attribute values

69

*/

70

void setEscapeAttributes(boolean escapeAttributes)

71

boolean isEscapeAttributes()

72

73

/**

74

* Get markup helper for advanced operations

75

* @return MarkupBuilderHelper instance

76

*/

77

MarkupBuilderHelper getMkp()

78

79

/**

80

* Set additional character filters for text content

81

* @param additionalFilters - List of character filter functions

82

*/

83

void setAdditionalFilters(List<Function<Character, Optional<String>>> additionalFilters)

84

85

/**

86

* Get additional character filters

87

* @return List of character filter functions

88

*/

89

List<Function<Character, Optional<String>>> getAdditionalFilters()

90

91

/**

92

* Get the underlying printer used for output

93

* @return IndentPrinter instance

94

*/

95

IndentPrinter getPrinter()

96

```

97

98

#### Character Filter Enum

99

100

```groovy { .api }

101

/**

102

* Character filtering options for MarkupBuilder

103

*/

104

enum CharFilter {

105

/** Strict XML character filtering */

106

XML_STRICT,

107

/** Filter all XML-related characters */

108

XML_ALL,

109

/** No character filtering */

110

NONE

111

}

112

```

113

114

**Usage Examples:**

115

116

```groovy

117

import groovy.xml.MarkupBuilder

118

119

// Basic XML generation

120

def writer = new StringWriter()

121

def xml = new MarkupBuilder(writer)

122

123

xml.books {

124

book(id: "1", title: "Groovy in Action") {

125

author("Dierk König")

126

price("49.99")

127

description {

128

mkp.yield("Comprehensive guide to ")

129

mkp.yieldUnescaped("<em>Groovy</em>")

130

mkp.yield(" programming")

131

}

132

}

133

book(id: "2", title: "Programming Groovy") {

134

author("Venkat Subramaniam")

135

price("45.99")

136

}

137

}

138

139

println writer.toString()

140

141

// Configuration example

142

def configuredXml = new MarkupBuilder(new StringWriter())

143

configuredXml.setDoubleQuotes(true)

144

configuredXml.setExpandEmptyElements(true)

145

configuredXml.setOmitNullAttributes(true)

146

147

configuredXml.catalog {

148

item(id: "123", category: null, title: "Sample") // category omitted

149

emptyItem() // Expanded as <emptyItem></emptyItem>

150

}

151

152

// Namespace example

153

xml.html("xmlns": "http://www.w3.org/1999/xhtml") {

154

head {

155

title("Sample Page")

156

}

157

body {

158

h1("Welcome")

159

p("This is a sample XHTML document")

160

}

161

}

162

```

163

164

---

165

166

### MarkupBuilderHelper

167

168

Helper class providing advanced markup operations including raw content insertion, comments, and XML declarations.

169

170

```groovy { .api }

171

/**

172

* Constructor (typically accessed via MarkupBuilder.getMkp())

173

* @param builder - Parent MarkupBuilder

174

*/

175

MarkupBuilderHelper(MarkupBuilder builder)

176

177

/**

178

* Yield escaped content

179

* @param value - Content to yield with escaping

180

*/

181

void yield(Object value)

182

void yield(String value)

183

184

/**

185

* Yield unescaped raw content

186

* @param value - Raw content to yield without escaping

187

*/

188

void yieldUnescaped(Object value)

189

void yieldUnescaped(String value)

190

191

/**

192

* Add XML comment

193

* @param value - Comment text

194

*/

195

void comment(String value)

196

197

/**

198

* Add XML declaration

199

* @param args - Declaration attributes (version, encoding, standalone)

200

*/

201

void xmlDeclaration(Map<String, Object> args)

202

203

/**

204

* Add processing instruction

205

* @param args - Map with PI target as key and attributes as value

206

*/

207

void pi(Map<String, Map<String, Object>> args)

208

```

209

210

**Usage Examples:**

211

212

```groovy

213

def writer = new StringWriter()

214

def xml = new MarkupBuilder(writer)

215

216

xml.document {

217

mkp.xmlDeclaration(version: "1.0", encoding: "UTF-8")

218

mkp.comment("Generated by Groovy XML")

219

220

root {

221

content {

222

mkp.yield("Safe content: ")

223

mkp.yield("<script>alert('safe')</script>") // Escaped

224

mkp.yieldUnescaped("<strong>Bold text</strong>") // Raw HTML

225

}

226

227

mkp.pi("xml-stylesheet": [type: "text/xsl", href: "style.xsl"])

228

}

229

}

230

```

231

232

---

233

234

### DOMBuilder

235

236

Builder for creating W3C DOM Document objects, providing integration with standard Java XML DOM APIs.

237

238

```groovy { .api }

239

/**

240

* Constructor with existing Document

241

* @param document - DOM Document to build upon

242

*/

243

DOMBuilder(Document document)

244

245

/**

246

* Constructor with DocumentBuilder

247

* @param documentBuilder - DocumentBuilder for document creation

248

*/

249

DOMBuilder(DocumentBuilder documentBuilder)

250

251

/**

252

* Create new DOMBuilder instance with default settings

253

* @return New DOMBuilder instance

254

*/

255

static DOMBuilder newInstance()

256

257

/**

258

* Create DOMBuilder with validation and namespace control

259

* @param validating - Enable DTD validation

260

* @param namespaceAware - Enable namespace processing

261

* @return New DOMBuilder instance

262

*/

263

static DOMBuilder newInstance(boolean validating, boolean namespaceAware)

264

265

/**

266

* Parse XML text into DOM Document

267

* @param text - XML text to parse

268

* @return DOM Document

269

*/

270

Document parseText(String text)

271

```

272

273

#### Static Parse Methods

274

275

```groovy { .api }

276

/**

277

* Parse XML from Reader into DOM Document

278

* @param reader - Reader containing XML

279

* @return DOM Document

280

*/

281

static Document parse(Reader reader)

282

283

/**

284

* Parse with validation and namespace control

285

* @param reader - Reader containing XML

286

* @param validating - Enable DTD validation

287

* @param namespaceAware - Enable namespace processing

288

* @return DOM Document

289

*/

290

static Document parse(Reader reader, boolean validating, boolean namespaceAware)

291

292

/**

293

* Parse with full control over processing

294

* @param reader - Reader containing XML

295

* @param validating - Enable DTD validation

296

* @param namespaceAware - Enable namespace processing

297

* @param allowDocTypeDeclaration - Allow DOCTYPE declarations

298

* @return DOM Document

299

*/

300

static Document parse(Reader reader, boolean validating, boolean namespaceAware, boolean allowDocTypeDeclaration)

301

```

302

303

**Usage Examples:**

304

305

```groovy

306

import groovy.xml.DOMBuilder

307

import org.w3c.dom.Document

308

309

// Create DOM using builder DSL

310

def builder = DOMBuilder.newInstance()

311

Document doc = builder.books {

312

book(id: "1") {

313

title("Groovy Programming")

314

author("John Doe")

315

}

316

book(id: "2") {

317

title("XML Processing")

318

author("Jane Smith")

319

}

320

}

321

322

// Access DOM elements

323

println doc.documentElement.tagName // "books"

324

def books = doc.getElementsByTagName("book")

325

println books.length // 2

326

327

// Parse existing XML into DOM

328

def xmlText = '<catalog><item>Sample</item></catalog>'

329

Document parsedDoc = builder.parseText(xmlText)

330

331

// Static parsing

332

Document staticDoc = DOMBuilder.parse(new StringReader(xmlText))

333

334

// Namespace-aware DOM building

335

def nsBuilder = DOMBuilder.newInstance(false, true)

336

Document nsDoc = nsBuilder.catalog("xmlns:lib": "http://library.org") {

337

"lib:book"(isbn: "123") {

338

"lib:title"("Advanced XML")

339

}

340

}

341

```

342

343

---

344

345

### StreamingMarkupBuilder

346

347

Memory-efficient builder for generating large XML documents using streaming output. Ideal for generating XML that doesn't fit in memory or when processing large datasets.

348

349

```groovy { .api }

350

/**

351

* Default constructor

352

*/

353

StreamingMarkupBuilder()

354

355

/**

356

* Bind closure to create streamable markup

357

* @param closure - Closure defining markup structure

358

* @return Writable object for streaming output

359

*/

360

def bind(Closure closure)

361

362

/**

363

* Bind Node object to create streamable markup

364

* @param node - Node to convert to streaming markup

365

* @return Writable object for streaming output

366

*/

367

def bindNode(Node node)

368

```

369

370

#### Configuration Properties

371

372

```groovy { .api }

373

/**

374

* Control quote style (default: false for single quotes)

375

*/

376

boolean useDoubleQuotes

377

378

/**

379

* Control empty element expansion (default: false)

380

*/

381

boolean expandEmptyElements

382

383

/**

384

* Set output encoding (default: null for platform default)

385

*/

386

def encoding

387

```

388

389

**Usage Examples:**

390

391

```groovy

392

import groovy.xml.StreamingMarkupBuilder

393

394

// Basic streaming markup

395

def builder = new StreamingMarkupBuilder()

396

def markup = builder.bind {

397

catalog {

398

(1..1000).each { i ->

399

book(id: i) {

400

title("Book ${i}")

401

price(Math.random() * 100)

402

}

403

}

404

}

405

}

406

407

// Write to file efficiently

408

new File("large-catalog.xml").withWriter { writer ->

409

markup.writeTo(writer)

410

}

411

412

// Configuration

413

builder.useDoubleQuotes = true

414

builder.expandEmptyElements = true

415

builder.encoding = "UTF-8"

416

417

// Streaming with XML declaration

418

def markupWithDecl = builder.bind {

419

mkp.xmlDeclaration(version: "1.0", encoding: "UTF-8")

420

mkp.comment("Generated streaming XML")

421

422

data {

423

records {

424

(1..10000).each { i ->

425

record(id: i, timestamp: new Date()) {

426

value(Math.random())

427

}

428

}

429

}

430

}

431

}

432

433

// Stream to OutputStream

434

new FileOutputStream("data.xml").withStream { stream ->

435

markupWithDecl.writeTo(new OutputStreamWriter(stream, "UTF-8"))

436

}

437

438

// Convert existing Node to streaming

439

def parser = new XmlParser()

440

def existingNode = parser.parseText('<sample><item>test</item></sample>')

441

def streamableNode = builder.bindNode(existingNode)

442

println streamableNode.toString()

443

```

444

445

---

446

447

### Additional Builders

448

449

#### StaxBuilder

450

451

```groovy { .api }

452

/**

453

* Builder using StAX XMLStreamWriter

454

* @param xmlStreamWriter - StAX XMLStreamWriter for output

455

*/

456

StaxBuilder(XMLStreamWriter xmlStreamWriter)

457

```

458

459

#### SAXBuilder

460

461

```groovy { .api }

462

/**

463

* Builder generating SAX events

464

* @param handler - ContentHandler for SAX events

465

*/

466

SAXBuilder(ContentHandler handler)

467

```

468

469

#### StreamingDOMBuilder and StreamingSAXBuilder

470

471

```groovy { .api }

472

// Streaming builders extending AbstractStreamingBuilder

473

class StreamingDOMBuilder extends AbstractStreamingBuilder

474

class StreamingSAXBuilder extends AbstractStreamingBuilder

475

```

476

477

**Usage Examples:**

478

479

```groovy

480

import groovy.xml.*

481

import javax.xml.stream.XMLOutputFactory

482

import javax.xml.transform.stream.StreamResult

483

484

// StAX builder example

485

def outputFactory = XMLOutputFactory.newInstance()

486

def stringWriter = new StringWriter()

487

def streamWriter = outputFactory.createXMLStreamWriter(stringWriter)

488

489

def staxBuilder = new StaxBuilder(streamWriter)

490

staxBuilder.library {

491

book(title: "StAX Processing") {

492

author("XML Expert")

493

}

494

}

495

streamWriter.close()

496

println stringWriter.toString()

497

498

// SAX builder example

499

def handler = new DefaultHandler() {

500

void startElement(String uri, String localName, String qName, Attributes attributes) {

501

println "Start: $qName"

502

}

503

}

504

505

def saxBuilder = new SAXBuilder(handler)

506

saxBuilder.catalog {

507

item("Test Item")

508

}

509

```

510

511

---

512

513

### Entity

514

515

Provides comprehensive XML entity constants for use in XML generation, offering all standard HTML and XML entities as static final constants.

516

517

```groovy { .api }

518

/**

519

* Constructor with entity name

520

* @param name - Entity name as string

521

*/

522

Entity(String name)

523

524

/**

525

* Constructor with entity code

526

* @param code - Entity code as integer

527

*/

528

Entity(int code)

529

```

530

531

#### Standard Entity Constants

532

533

```groovy { .api }

534

// Common entities

535

static final Entity nbsp, iexcl, cent, pound, curren, yen, brvbar, sect, uml, copy

536

static final Entity ordf, laquo, not, shy, reg, macr, deg, plusmn, sup2, sup3

537

static final Entity acute, micro, para, middot, cedil, sup1, ordm, raquo

538

static final Entity frac14, frac12, frac34, iquest

539

540

// Latin characters (uppercase)

541

static final Entity Agrave, Aacute, Acirc, Atilde, Auml, Aring, AElig, Ccedil

542

static final Entity Egrave, Eacute, Ecirc, Euml, Igrave, Iacute, Icirc, Iuml

543

static final Entity ETH, Ntilde, Ograve, Oacute, Ocirc, Otilde, Ouml, times

544

static final Entity Oslash, Ugrave, Uacute, Ucirc, Uuml, Yacute, THORN

545

546

// Latin characters (lowercase)

547

static final Entity szlig, agrave, aacute, acirc, atilde, auml, aring, aelig, ccedil

548

static final Entity egrave, eacute, ecirc, euml, igrave, iacute, icirc, iuml

549

static final Entity eth, ntilde, ograve, oacute, ocirc, otilde, ouml, divide

550

static final Entity oslash, ugrave, uacute, ucirc, uuml, yacute, thorn, yuml

551

552

// Special characters

553

static final Entity lt, gt, amp, apos, quot, OElig, oelig, Scaron, scaron, Yuml

554

static final Entity circ, tilde, ensp, emsp, thinsp, zwnj, zwj, lrm, rlm

555

static final Entity ndash, mdash, lsquo, rsquo, sbquo, ldquo, rdquo, bdquo

556

static final Entity dagger, Dagger, permil, lsaquo, rsaquo, euro

557

```

558

559

**Usage Examples:**

560

561

```groovy

562

import groovy.xml.MarkupBuilder

563

import groovy.xml.Entity

564

565

// Using entities in markup generation

566

def writer = new StringWriter()

567

def xml = new MarkupBuilder(writer)

568

569

xml.document {

570

title("Price: ${Entity.pound}25.99") // Price: £25.99

571

content {

572

p("Copyright ${Entity.copy} 2023") // Copyright © 2023

573

p("Temperature: 25${Entity.deg}C") // Temperature: 25°C

574

quote("${Entity.ldquo}Hello World${Entity.rdquo}") // "Hello World"

575

}

576

math {

577

formula("x${Entity.sup2} + y${Entity.sup2} = z${Entity.sup2}") // x² + y² = z²

578

fraction("${Entity.frac12} + ${Entity.frac14} = ${Entity.frac34}") // ½ + ¼ = ¾

579

}

580

}

581

582

println writer.toString()

583

584

// Using entities for safe XML generation

585

xml.data {

586

comparison("5 ${Entity.lt} 10 ${Entity.amp} 10 ${Entity.gt} 5") // 5 < 10 & 10 > 5

587

quoted("He said ${Entity.quot}Hello${Entity.quot}") // He said "Hello"

588

}

589

590

// Custom entity usage

591

def customEntity = new Entity("custom")

592

def codeEntity = new Entity(8364) // Euro symbol by code

593

594

xml.custom {

595

field(customEntity.toString())

596

symbol(codeEntity.toString())

597

}

598

599

// Build method for integration with builders

600

customEntity.build(xml) // Integrates entity with builder

601

```

602

603

---

604

605

### Additional Builder Classes

606

607

#### SAXBuilder

608

609

Builder for generating SAX events directly, useful for integration with SAX-based processing chains.

610

611

```groovy { .api }

612

/**

613

* Constructor with ContentHandler for SAX events

614

* @param handler - ContentHandler to receive SAX events

615

*/

616

SAXBuilder(ContentHandler handler)

617

```

618

619

#### StaxBuilder

620

621

Builder using StAX XMLStreamWriter for efficient streaming XML generation.

622

623

```groovy { .api }

624

/**

625

* Constructor with XMLStreamWriter

626

* @param xmlStreamWriter - StAX XMLStreamWriter for output

627

*/

628

StaxBuilder(XMLStreamWriter xmlStreamWriter)

629

```

630

631

#### StreamingDOMBuilder and StreamingSAXBuilder

632

633

Advanced streaming builders extending AbstractStreamingBuilder for specialized streaming scenarios.

634

635

```groovy { .api }

636

/**

637

* Streaming DOM builder for large document generation

638

*/

639

class StreamingDOMBuilder extends AbstractStreamingBuilder

640

641

/**

642

* Streaming SAX builder for event-based generation

643

*/

644

class StreamingSAXBuilder extends AbstractStreamingBuilder

645

```

646

647

**Usage Examples:**

648

649

```groovy

650

import groovy.xml.*

651

import javax.xml.stream.XMLOutputFactory

652

import javax.xml.transform.sax.SAXResult

653

import org.xml.sax.helpers.DefaultHandler

654

655

// StAX builder example

656

def outputFactory = XMLOutputFactory.newInstance()

657

def stringWriter = new StringWriter()

658

def streamWriter = outputFactory.createXMLStreamWriter(stringWriter)

659

660

def staxBuilder = new StaxBuilder(streamWriter)

661

staxBuilder.library {

662

book(title: "StAX Processing") {

663

author("XML Expert")

664

chapters {

665

chapter(number: "1", "Introduction to StAX")

666

chapter(number: "2", "Advanced StAX Features")

667

}

668

}

669

}

670

streamWriter.close()

671

println stringWriter.toString()

672

673

// SAX builder example

674

def handler = new DefaultHandler() {

675

void startElement(String uri, String localName, String qName, Attributes attributes) {

676

println "Start element: $qName"

677

if (attributes.length > 0) {

678

for (int i = 0; i < attributes.length; i++) {

679

println " Attribute: ${attributes.getQName(i)} = ${attributes.getValue(i)}"

680

}

681

}

682

}

683

684

void endElement(String uri, String localName, String qName) {

685

println "End element: $qName"

686

}

687

688

void characters(char[] ch, int start, int length) {

689

def text = new String(ch, start, length).trim()

690

if (text) {

691

println "Text content: $text"

692

}

693

}

694

}

695

696

def saxBuilder = new SAXBuilder(handler)

697

saxBuilder.catalog {

698

item(id: "1", "First Item")

699

item(id: "2", "Second Item")

700

}

701

```