Groovy XML support library providing comprehensive XML processing capabilities including parsing, manipulation, and generation of XML documents using Groovy's native XML handling features, XmlSlurper, and XmlParser APIs
—
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.
Category class that adds GPath-style operations to Java's DOM classes, allowing natural Groovy syntax for DOM navigation and manipulation.
/**
* Get global whitespace trimming setting
* @return true if whitespace is trimmed globally
*/
static synchronized boolean isGlobalTrimWhitespace()
/**
* Set global whitespace trimming for all DOM operations
* @param trimWhitespace - true to trim whitespace globally
*/
static synchronized void setGlobalTrimWhitespace(boolean trimWhitespace)
/**
* Get global ignorable whitespace preservation setting
* @return true if ignorable whitespace is preserved
*/
static synchronized boolean isGlobalKeepIgnorableWhitespace()
/**
* Set global ignorable whitespace preservation
* @param keepIgnorableWhitespace - true to preserve ignorable whitespace
*/
static synchronized void setGlobalKeepIgnorableWhitespace(boolean keepIgnorableWhitespace)/**
* Get child elements by name (GPath-style access)
* @param element - Parent Element
* @param elementName - Name of child elements to find
* @return Child elements or single element
*/
static Object get(Element element, String elementName)
/**
* Get elements from NodeList by name
* @param nodeList - NodeList to search
* @param elementName - Element name to find
* @return Matching elements
*/
static Object get(NodeList nodeList, String elementName)
/**
* Get attribute from NamedNodeMap
* @param nodeMap - NamedNodeMap to search
* @param elementName - Attribute name
* @return Attribute value
*/
static Object get(NamedNodeMap nodeMap, String elementName)
/**
* Get element attributes as NamedNodeMap
* @param element - Element to get attributes from
* @return NamedNodeMap of attributes
*/
static NamedNodeMap attributes(Element element)
/**
* Get node name
* @param node - Node to get name from
* @return Node name as string
*/
static String name(Node node)
/**
* Get parent node
* @param node - Child node
* @return Parent Node
*/
static Node parent(Node node)/**
* Get text content of node and all descendants
* @param node - Node to get text from
* @return Combined text content
*/
static String text(Node node)
/**
* Get text content from all nodes in NodeList
* @param nodeList - NodeList to get text from
* @return Combined text content
*/
static String text(NodeList nodeList)
/**
* Get direct text content of element (excludes descendants)
* @param element - Element to get local text from
* @return List of direct text content
*/
static List<String> localText(Element element)
/**
* Convert NodeList to List<Node>
* @param nodeList - NodeList to convert
* @return List of Node objects
*/
static List<Node> list(NodeList nodeList)/**
* Depth-first traversal of element tree
* @param element - Root element for traversal
* @return NodeList with depth-first ordered nodes
*/
static NodeList depthFirst(Element element)
/**
* Breadth-first traversal of element tree
* @param element - Root element for traversal
* @return NodeList with breadth-first ordered nodes
*/
static NodeList breadthFirst(Element element)
/**
* Get immediate children of element
* @param element - Parent element
* @return NodeList of child elements
*/
static NodeList children(Element element)/**
* Append new child element
* @param element - Parent element
* @param name - Name of new child element
* @return New child Element
*/
static Element appendNode(Element element, Object name)
/**
* Append child element with attributes
* @param element - Parent element
* @param name - Name of new child element
* @param attributes - Map of attributes
* @return New child Element
*/
static Element appendNode(Element element, Object name, Map attributes)
/**
* Append child element with text content
* @param element - Parent element
* @param name - Name of new child element
* @param value - Text content for new element
* @return New child Element
*/
static Element appendNode(Element element, Object name, String value)
/**
* Append child element with attributes and text content
* @param element - Parent element
* @param name - Name of new child element
* @param attributes - Map of attributes
* @param value - Text content
* @return New child Element
*/
static Element appendNode(Element element, Object name, Map attributes, String value)
/**
* Set text content of element
* @param element - Element to modify
* @param value - New text content
*/
static void setValue(Element element, String value)
/**
* Set element property/attribute value
* @param element - Element to modify
* @param property - Property/attribute name
* @param value - New value
*/
static void putAt(Element element, String property, Object value)
/**
* Add child nodes using closure
* @param element - Parent element
* @param closure - Closure defining new child content
*/
static void plus(Element element, Closure closure)
/**
* Add child nodes to NodeList using closure
* @param nodeList - NodeList to extend
* @param closure - Closure defining new content
*/
static void plus(NodeList nodeList, Closure closure)/**
* Get child node by index
* @param node - Parent node
* @param index - Child index
* @return Child Node at index
*/
static Node getAt(Node node, int index)
/**
* Get node range from parent
* @param node - Parent node
* @param range - IntRange of indices
* @return NodeList with nodes in range
*/
static NodeList getAt(Node node, IntRange range)/**
* Get size of NamedNodeMap
* @param namedNodeMap - NamedNodeMap to measure
* @return Number of items
*/
static int size(NamedNodeMap namedNodeMap)
/**
* Get size of NodeList
* @param nodeList - NodeList to measure
* @return Number of nodes
*/
static int size(NodeList nodeList)
/**
* Check if NodeList is empty
* @param nodeList - NodeList to check
* @return true if empty
*/
static boolean isEmpty(NodeList nodeList)/**
* Evaluate XPath expression with specified return type
* @param node - Context node for XPath evaluation
* @param expression - XPath expression string
* @param returnType - javax.xml.namespace.QName specifying return type
* @return XPath evaluation result
*/
static Object xpath(Node node, String expression, javax.xml.namespace.QName returnType)
/**
* Evaluate XPath expression returning string result
* @param node - Context node for XPath evaluation
* @param expression - XPath expression string
* @return String result of XPath evaluation
*/
static String xpath(Node node, String expression)/**
* Replace node with content generated by closure
* @param self - Node to replace
* @param c - Closure generating replacement content
* @return New replacement Node
*/
static Node replaceNode(Node self, Closure c)
/**
* Replace nodes in NodesHolder with closure-generated content
* @param self - NodesHolder containing nodes to replace
* @param c - Closure generating replacement content
* @return New replacement Node
*/
static Node replaceNode(NodesHolder self, Closure c)/**
* Get node from NodeListsHolder by index
* @param o - NodeListsHolder to access
* @param i - Index of node
* @return Node at index
*/
static Node getAt(NodeListsHolder o, int i)
/**
* Get node from NodesHolder by index
* @param o - NodesHolder to access
* @param i - Index of node
* @return Node at index
*/
static Node getAt(NodesHolder o, int i)
/**
* Get node range from NodeListsHolder
* @param o - NodeListsHolder to access
* @param r - IntRange of indices
* @return NodeList with nodes in range
*/
static NodeList getAt(NodeListsHolder o, IntRange r)
/**
* Get node range from NodesHolder
* @param o - NodesHolder to access
* @param r - IntRange of indices
* @return NodeList with nodes in range
*/
static NodeList getAt(NodesHolder o, IntRange r)/**
* Internal NodeList implementation for DOM operations
*/
private static final class NodeListsHolder implements NodeList
/**
* Internal Node collection for DOM operations
*/
private static final class NodesHolder implements NodeListUsage Examples:
import groovy.xml.DOMBuilder
import groovy.xml.dom.DOMCategory
import org.w3c.dom.*
// Create DOM document
def builder = DOMBuilder.newInstance()
Document doc = builder.library {
book(id: "1", isbn: "123-456") {
title("Groovy Programming")
author("John Doe")
price("49.99")
categories {
category("Programming")
category("Groovy")
}
}
book(id: "2", isbn: "789-012") {
title("XML Processing")
author("Jane Smith")
price("39.99")
categories {
category("XML")
category("Data Processing")
}
}
}
// Use DOMCategory for enhanced DOM operations
use(DOMCategory) {
Element root = doc.documentElement
// GPath-style navigation
println root.book.size() // 2
println root.book[0].title.text() // "Groovy Programming"
println root.book*.@id // ["1", "2"]
println root.book*.title*.text() // ["Groovy Programming", "XML Processing"]
// Attribute access
def firstBook = root.book[0]
println firstBook.@isbn // "123-456"
println firstBook.attributes().getNamedItem("id").value // "1"
// Text content access
println firstBook.author.text() // "John Doe"
println firstBook.categories.category*.text() // ["Programming", "Groovy"]
// Tree traversal
root.depthFirst().each { node ->
if (node.nodeType == Node.ELEMENT_NODE) {
println "Element: ${node.name()}"
}
}
// Modification operations
def newBook = root.appendNode("book", [id: "3", isbn: "345-678"])
newBook.appendNode("title", "Advanced Groovy")
newBook.appendNode("author", "Expert Author")
newBook.appendNode("price", "59.99")
// Set element content
def description = newBook.appendNode("description")
description.setValue("Comprehensive guide to advanced Groovy techniques")
// Add using closure
newBook + {
tags('new-release': 'true') {
tag('advanced')
tag('groovy')
}
}
// XPath operations
def expensiveBooks = root.xpath("//book[price > 45]", javax.xml.xpath.XPathConstants.NODESET)
println "Expensive books: ${expensiveBooks.length}"
def firstTitle = root.xpath("//book[1]/title/text()")
println "First title: ${firstTitle}"
// Global configuration
DOMCategory.setGlobalTrimWhitespace(true)
DOMCategory.setGlobalKeepIgnorableWhitespace(false)
// Collection operations
def allTitles = root.book.title.list()
allTitles.each { titleElement ->
println "Title element: ${titleElement.textContent}"
}
// Range operations
def firstTwoBooks = root.book[0..1]
println "First two books: ${firstTwoBooks.size()}"
// Parent navigation
def author = root.book[0].author
def book = author.parent()
println "Author's book ID: ${book.@id}"
// Local text (direct text content only)
def mixed = root.appendNode("mixed")
mixed.appendTextNode("Direct text")
mixed.appendNode("child", "Child text")
mixed.appendTextNode(" More direct text")
println mixed.localText() // ["Direct text", " More direct text"]
println mixed.text() // "Direct textChild text More direct text"
}
// Working with existing DOM from other sources
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance()
DocumentBuilder docBuilder = factory.newDocumentBuilder()
Document existingDoc = docBuilder.parse(new File("existing.xml"))
use(DOMCategory) {
// Apply same GPath operations to existing DOM
Element root = existingDoc.documentElement
println root.name()
// Find and modify elements
def targetElement = root.xpath("//target").item(0)
if (targetElement) {
targetElement.setValue("Updated content")
targetElement.putAt("modified", "true")
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-groovy--groovy-xml