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

dom-processing.mddocs/

0

# DOM Processing

1

2

Enhanced DOM processing with Groovy category methods providing GPath-style navigation and manipulation for standard W3C DOM objects. Enables idiomatic Groovy syntax for working with existing DOM documents.

3

4

## Capabilities

5

6

### DOMCategory

7

8

Category class that adds GPath-style operations to Java's DOM classes, allowing natural Groovy syntax for DOM navigation and manipulation.

9

10

#### Global Configuration

11

12

```groovy { .api }

13

/**

14

* Get global whitespace trimming setting

15

* @return true if whitespace is trimmed globally

16

*/

17

static synchronized boolean isGlobalTrimWhitespace()

18

19

/**

20

* Set global whitespace trimming for all DOM operations

21

* @param trimWhitespace - true to trim whitespace globally

22

*/

23

static synchronized void setGlobalTrimWhitespace(boolean trimWhitespace)

24

25

/**

26

* Get global ignorable whitespace preservation setting

27

* @return true if ignorable whitespace is preserved

28

*/

29

static synchronized boolean isGlobalKeepIgnorableWhitespace()

30

31

/**

32

* Set global ignorable whitespace preservation

33

* @param keepIgnorableWhitespace - true to preserve ignorable whitespace

34

*/

35

static synchronized void setGlobalKeepIgnorableWhitespace(boolean keepIgnorableWhitespace)

36

```

37

38

#### Navigation Methods

39

40

```groovy { .api }

41

/**

42

* Get child elements by name (GPath-style access)

43

* @param element - Parent Element

44

* @param elementName - Name of child elements to find

45

* @return Child elements or single element

46

*/

47

static Object get(Element element, String elementName)

48

49

/**

50

* Get elements from NodeList by name

51

* @param nodeList - NodeList to search

52

* @param elementName - Element name to find

53

* @return Matching elements

54

*/

55

static Object get(NodeList nodeList, String elementName)

56

57

/**

58

* Get attribute from NamedNodeMap

59

* @param nodeMap - NamedNodeMap to search

60

* @param elementName - Attribute name

61

* @return Attribute value

62

*/

63

static Object get(NamedNodeMap nodeMap, String elementName)

64

65

/**

66

* Get element attributes as NamedNodeMap

67

* @param element - Element to get attributes from

68

* @return NamedNodeMap of attributes

69

*/

70

static NamedNodeMap attributes(Element element)

71

72

/**

73

* Get node name

74

* @param node - Node to get name from

75

* @return Node name as string

76

*/

77

static String name(Node node)

78

79

/**

80

* Get parent node

81

* @param node - Child node

82

* @return Parent Node

83

*/

84

static Node parent(Node node)

85

```

86

87

#### Content Access Methods

88

89

```groovy { .api }

90

/**

91

* Get text content of node and all descendants

92

* @param node - Node to get text from

93

* @return Combined text content

94

*/

95

static String text(Node node)

96

97

/**

98

* Get text content from all nodes in NodeList

99

* @param nodeList - NodeList to get text from

100

* @return Combined text content

101

*/

102

static String text(NodeList nodeList)

103

104

/**

105

* Get direct text content of element (excludes descendants)

106

* @param element - Element to get local text from

107

* @return List of direct text content

108

*/

109

static List<String> localText(Element element)

110

111

/**

112

* Convert NodeList to List<Node>

113

* @param nodeList - NodeList to convert

114

* @return List of Node objects

115

*/

116

static List<Node> list(NodeList nodeList)

117

```

118

119

#### Tree Traversal Methods

120

121

```groovy { .api }

122

/**

123

* Depth-first traversal of element tree

124

* @param element - Root element for traversal

125

* @return NodeList with depth-first ordered nodes

126

*/

127

static NodeList depthFirst(Element element)

128

129

/**

130

* Breadth-first traversal of element tree

131

* @param element - Root element for traversal

132

* @return NodeList with breadth-first ordered nodes

133

*/

134

static NodeList breadthFirst(Element element)

135

136

/**

137

* Get immediate children of element

138

* @param element - Parent element

139

* @return NodeList of child elements

140

*/

141

static NodeList children(Element element)

142

```

143

144

#### Modification Methods

145

146

```groovy { .api }

147

/**

148

* Append new child element

149

* @param element - Parent element

150

* @param name - Name of new child element

151

* @return New child Element

152

*/

153

static Element appendNode(Element element, Object name)

154

155

/**

156

* Append child element with attributes

157

* @param element - Parent element

158

* @param name - Name of new child element

159

* @param attributes - Map of attributes

160

* @return New child Element

161

*/

162

static Element appendNode(Element element, Object name, Map attributes)

163

164

/**

165

* Append child element with text content

166

* @param element - Parent element

167

* @param name - Name of new child element

168

* @param value - Text content for new element

169

* @return New child Element

170

*/

171

static Element appendNode(Element element, Object name, String value)

172

173

/**

174

* Append child element with attributes and text content

175

* @param element - Parent element

176

* @param name - Name of new child element

177

* @param attributes - Map of attributes

178

* @param value - Text content

179

* @return New child Element

180

*/

181

static Element appendNode(Element element, Object name, Map attributes, String value)

182

183

/**

184

* Set text content of element

185

* @param element - Element to modify

186

* @param value - New text content

187

*/

188

static void setValue(Element element, String value)

189

190

/**

191

* Set element property/attribute value

192

* @param element - Element to modify

193

* @param property - Property/attribute name

194

* @param value - New value

195

*/

196

static void putAt(Element element, String property, Object value)

197

198

/**

199

* Add child nodes using closure

200

* @param element - Parent element

201

* @param closure - Closure defining new child content

202

*/

203

static void plus(Element element, Closure closure)

204

205

/**

206

* Add child nodes to NodeList using closure

207

* @param nodeList - NodeList to extend

208

* @param closure - Closure defining new content

209

*/

210

static void plus(NodeList nodeList, Closure closure)

211

```

212

213

#### Indexing Operations

214

215

```groovy { .api }

216

/**

217

* Get child node by index

218

* @param node - Parent node

219

* @param index - Child index

220

* @return Child Node at index

221

*/

222

static Node getAt(Node node, int index)

223

224

/**

225

* Get node range from parent

226

* @param node - Parent node

227

* @param range - IntRange of indices

228

* @return NodeList with nodes in range

229

*/

230

static NodeList getAt(Node node, IntRange range)

231

```

232

233

#### Utility Methods

234

235

```groovy { .api }

236

/**

237

* Get size of NamedNodeMap

238

* @param namedNodeMap - NamedNodeMap to measure

239

* @return Number of items

240

*/

241

static int size(NamedNodeMap namedNodeMap)

242

243

/**

244

* Get size of NodeList

245

* @param nodeList - NodeList to measure

246

* @return Number of nodes

247

*/

248

static int size(NodeList nodeList)

249

250

/**

251

* Check if NodeList is empty

252

* @param nodeList - NodeList to check

253

* @return true if empty

254

*/

255

static boolean isEmpty(NodeList nodeList)

256

```

257

258

#### XPath Support

259

260

```groovy { .api }

261

/**

262

* Evaluate XPath expression with specified return type

263

* @param node - Context node for XPath evaluation

264

* @param expression - XPath expression string

265

* @param returnType - javax.xml.namespace.QName specifying return type

266

* @return XPath evaluation result

267

*/

268

static Object xpath(Node node, String expression, javax.xml.namespace.QName returnType)

269

270

/**

271

* Evaluate XPath expression returning string result

272

* @param node - Context node for XPath evaluation

273

* @param expression - XPath expression string

274

* @return String result of XPath evaluation

275

*/

276

static String xpath(Node node, String expression)

277

```

278

279

#### Node Replacement Methods

280

281

```groovy { .api }

282

/**

283

* Replace node with content generated by closure

284

* @param self - Node to replace

285

* @param c - Closure generating replacement content

286

* @return New replacement Node

287

*/

288

static Node replaceNode(Node self, Closure c)

289

290

/**

291

* Replace nodes in NodesHolder with closure-generated content

292

* @param self - NodesHolder containing nodes to replace

293

* @param c - Closure generating replacement content

294

* @return New replacement Node

295

*/

296

static Node replaceNode(NodesHolder self, Closure c)

297

```

298

299

#### Enhanced Indexing Operations

300

301

```groovy { .api }

302

/**

303

* Get node from NodeListsHolder by index

304

* @param o - NodeListsHolder to access

305

* @param i - Index of node

306

* @return Node at index

307

*/

308

static Node getAt(NodeListsHolder o, int i)

309

310

/**

311

* Get node from NodesHolder by index

312

* @param o - NodesHolder to access

313

* @param i - Index of node

314

* @return Node at index

315

*/

316

static Node getAt(NodesHolder o, int i)

317

318

/**

319

* Get node range from NodeListsHolder

320

* @param o - NodeListsHolder to access

321

* @param r - IntRange of indices

322

* @return NodeList with nodes in range

323

*/

324

static NodeList getAt(NodeListsHolder o, IntRange r)

325

326

/**

327

* Get node range from NodesHolder

328

* @param o - NodesHolder to access

329

* @param r - IntRange of indices

330

* @return NodeList with nodes in range

331

*/

332

static NodeList getAt(NodesHolder o, IntRange r)

333

```

334

335

#### Internal Helper Classes

336

337

```groovy { .api }

338

/**

339

* Internal NodeList implementation for DOM operations

340

*/

341

private static final class NodeListsHolder implements NodeList

342

343

/**

344

* Internal Node collection for DOM operations

345

*/

346

private static final class NodesHolder implements NodeList

347

```

348

349

**Usage Examples:**

350

351

```groovy

352

import groovy.xml.DOMBuilder

353

import groovy.xml.dom.DOMCategory

354

import org.w3c.dom.*

355

356

// Create DOM document

357

def builder = DOMBuilder.newInstance()

358

Document doc = builder.library {

359

book(id: "1", isbn: "123-456") {

360

title("Groovy Programming")

361

author("John Doe")

362

price("49.99")

363

categories {

364

category("Programming")

365

category("Groovy")

366

}

367

}

368

book(id: "2", isbn: "789-012") {

369

title("XML Processing")

370

author("Jane Smith")

371

price("39.99")

372

categories {

373

category("XML")

374

category("Data Processing")

375

}

376

}

377

}

378

379

// Use DOMCategory for enhanced DOM operations

380

use(DOMCategory) {

381

Element root = doc.documentElement

382

383

// GPath-style navigation

384

println root.book.size() // 2

385

println root.book[0].title.text() // "Groovy Programming"

386

println root.book*.@id // ["1", "2"]

387

println root.book*.title*.text() // ["Groovy Programming", "XML Processing"]

388

389

// Attribute access

390

def firstBook = root.book[0]

391

println firstBook.@isbn // "123-456"

392

println firstBook.attributes().getNamedItem("id").value // "1"

393

394

// Text content access

395

println firstBook.author.text() // "John Doe"

396

println firstBook.categories.category*.text() // ["Programming", "Groovy"]

397

398

// Tree traversal

399

root.depthFirst().each { node ->

400

if (node.nodeType == Node.ELEMENT_NODE) {

401

println "Element: ${node.name()}"

402

}

403

}

404

405

// Modification operations

406

def newBook = root.appendNode("book", [id: "3", isbn: "345-678"])

407

newBook.appendNode("title", "Advanced Groovy")

408

newBook.appendNode("author", "Expert Author")

409

newBook.appendNode("price", "59.99")

410

411

// Set element content

412

def description = newBook.appendNode("description")

413

description.setValue("Comprehensive guide to advanced Groovy techniques")

414

415

// Add using closure

416

newBook + {

417

tags('new-release': 'true') {

418

tag('advanced')

419

tag('groovy')

420

}

421

}

422

423

// XPath operations

424

def expensiveBooks = root.xpath("//book[price > 45]", javax.xml.xpath.XPathConstants.NODESET)

425

println "Expensive books: ${expensiveBooks.length}"

426

427

def firstTitle = root.xpath("//book[1]/title/text()")

428

println "First title: ${firstTitle}"

429

430

// Global configuration

431

DOMCategory.setGlobalTrimWhitespace(true)

432

DOMCategory.setGlobalKeepIgnorableWhitespace(false)

433

434

// Collection operations

435

def allTitles = root.book.title.list()

436

allTitles.each { titleElement ->

437

println "Title element: ${titleElement.textContent}"

438

}

439

440

// Range operations

441

def firstTwoBooks = root.book[0..1]

442

println "First two books: ${firstTwoBooks.size()}"

443

444

// Parent navigation

445

def author = root.book[0].author

446

def book = author.parent()

447

println "Author's book ID: ${book.@id}"

448

449

// Local text (direct text content only)

450

def mixed = root.appendNode("mixed")

451

mixed.appendTextNode("Direct text")

452

mixed.appendNode("child", "Child text")

453

mixed.appendTextNode(" More direct text")

454

455

println mixed.localText() // ["Direct text", " More direct text"]

456

println mixed.text() // "Direct textChild text More direct text"

457

}

458

459

// Working with existing DOM from other sources

460

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance()

461

DocumentBuilder docBuilder = factory.newDocumentBuilder()

462

Document existingDoc = docBuilder.parse(new File("existing.xml"))

463

464

use(DOMCategory) {

465

// Apply same GPath operations to existing DOM

466

Element root = existingDoc.documentElement

467

println root.name()

468

469

// Find and modify elements

470

def targetElement = root.xpath("//target").item(0)

471

if (targetElement) {

472

targetElement.setValue("Updated content")

473

targetElement.putAt("modified", "true")

474

}

475

}

476

```