Apache Groovy - A powerful multi-faceted programming language for the JVM platform with comprehensive module support
—
Groovy provides comprehensive XML support through multiple approaches: XmlSlurper for GPath-based navigation, XmlParser for DOM-style parsing, and various builders for XML generation.
High-level XML parser that provides GPath navigation capabilities for easy XML traversal.
class XmlSlurper {
XmlSlurper()
XmlSlurper(boolean validating, boolean namespaceAware)
XmlSlurper(XMLReader reader)
XmlSlurper(SAXParser parser)
XmlSlurper(boolean validating, boolean namespaceAware, boolean allowDocTypeDeclaration)
GPathResult parseText(String text)
GPathResult parse(File file)
GPathResult parse(InputStream input)
GPathResult parse(Reader reader)
GPathResult parse(InputSource input)
GPathResult parse(String uri)
GPathResult parse(Path path)
void setFeature(String feature, boolean value)
boolean getFeature(String feature)
void setProperty(String property, Object value)
Object getProperty(String property)
EntityResolver getEntityResolver()
void setEntityResolver(EntityResolver resolver)
ErrorHandler getErrorHandler()
void setErrorHandler(ErrorHandler handler)
}Result object from XmlSlurper that supports GPath navigation syntax.
abstract class GPathResult implements Writable {
abstract String name()
abstract Object text()
abstract GPathResult parent()
abstract Iterator childNodes()
abstract Iterator iterator()
abstract GPathResult find(Closure closure)
abstract GPathResult findAll(Closure closure)
abstract Iterator depthFirst()
abstract Iterator breadthFirst()
int size()
boolean isEmpty()
String toString()
Writer writeTo(Writer out)
GPathResult getProperty(String property)
void setProperty(String property, Object value)
// Attribute access
String attribute(String name)
GPathResult attributes()
// Navigation
GPathResult getAt(int index)
GPathResult getAt(String name)
GPathResult children()
}Usage examples:
import groovy.util.XmlSlurper
def xml = '''
<library>
<book id="1" category="fiction">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<year>1925</year>
</book>
<book id="2" category="science">
<title>Relativity</title>
<author>Albert Einstein</author>
<year>1916</year>
</book>
</library>
'''
def slurper = new XmlSlurper()
def library = slurper.parseText(xml)
// Navigate using GPath
assert library.book.size() == 2
assert library.book[0].title.text() == 'The Great Gatsby'
assert library.book.find { it.@category == 'science' }.title.text() == 'Relativity'
// Access attributes
assert library.book[0].@id == '1'
assert library.book[0].@category == 'fiction'
// Find all books by criteria
def fictionBooks = library.book.findAll { it.@category == 'fiction' }
def modernBooks = library.book.findAll { it.year.text() as Integer > 1920 }
// Iterate through elements
library.book.each { book ->
println "${book.title.text()} by ${book.author.text()}"
}DOM-style XML parser that creates a Node tree structure.
class XmlParser {
XmlParser()
XmlParser(boolean validating, boolean namespaceAware)
XmlParser(XMLReader reader)
Node parseText(String text)
Node parse(File file)
Node parse(InputStream input)
Node parse(Reader reader)
Node parse(InputSource input)
Node parse(URL url)
void setFeature(String feature, boolean value)
boolean getFeature(String feature)
void setProperty(String property, Object value)
Object getProperty(String property)
}Represents an XML element in the DOM-style tree.
class Node {
Node(Node parent, Object name)
Node(Node parent, Object name, Map attributes)
Node(Node parent, Object name, String value)
Node(Node parent, Object name, Map attributes, String value)
String name()
Object value()
String text()
List children()
Map attributes()
Node parent()
void setName(Object name)
void setValue(Object value)
void attributes(Map attributes)
void setParent(Node parent)
Object getAt(String key) // Attribute access
NodeList getAt(QName name) // Child access
void putAt(String key, Object value) // Set attribute
Node appendNode(Object name)
Node appendNode(Object name, Object value)
Node appendNode(Object name, Map attributes)
Node appendNode(Object name, Map attributes, Object value)
boolean remove(Node child)
NodeList depthFirst()
NodeList breadthFirst()
}Usage example:
import groovy.util.XmlParser
def parser = new XmlParser()
def library = parser.parseText(xml)
// Navigate the DOM tree
assert library.name() == 'library'
assert library.book.size() == 2
assert library.book[0].title.text() == 'The Great Gatsby'
// Modify the tree
library.book[0].appendNode('publisher', 'Scribner')
library.book[1].@category = 'physics' // Modify attribute
// Add new elements
def newBook = library.appendNode('book', [id: '3', category: 'mystery'])
newBook.appendNode('title', 'The Maltese Falcon')
newBook.appendNode('author', 'Dashiell Hammett')
newBook.appendNode('year', '1930')Builder for generating XML and HTML markup with a fluent API.
class MarkupBuilder extends BuilderSupport {
MarkupBuilder()
MarkupBuilder(Writer writer)
MarkupBuilder(IndentPrinter printer)
Object invokeMethod(String methodName, Object args)
void yield(Object value)
void yield(Object value, boolean escapeMarkup)
void yieldUnescaped(Object value)
Writer getWriter()
IndentPrinter getPrinter()
boolean isDoubleQuotes()
void setDoubleQuotes(boolean doubleQuotes)
boolean isExpandEmptyElements()
void setExpandEmptyElements(boolean expandEmptyElements)
boolean isOmitEmptyAttributes()
void setOmitEmptyAttributes(boolean omitEmptyAttributes)
boolean isOmitNullAttributes()
void setOmitNullAttributes(boolean omitNullAttributes)
}Usage examples:
import groovy.xml.MarkupBuilder
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.library {
book(id: '1', category: 'fiction') {
title('The Great Gatsby')
author('F. Scott Fitzgerald')
year(1925)
description {
yield('A classic American novel about the ', false)
em('Jazz Age')
yield('.', false)
}
}
book(id: '2', category: 'science') {
title('Relativity')
author('Albert Einstein')
year(1916)
}
}
println writer.toString()Memory-efficient builder for generating large XML documents using streaming output.
class StreamingMarkupBuilder {
StreamingMarkupBuilder()
Object bind(Closure closure)
void setEncoding(String encoding)
String getEncoding()
void setUseDoubleQuotes(boolean useDoubleQuotes)
boolean getUseDoubleQuotes()
}Usage example:
import groovy.xml.StreamingMarkupBuilder
def builder = new StreamingMarkupBuilder()
builder.encoding = 'UTF-8'
def xml = builder.bind {
library {
books.each { bookData ->
book(id: bookData.id, category: bookData.category) {
title(bookData.title)
author(bookData.author)
year(bookData.year)
}
}
}
}
println xml.toString()Builder that creates a DOM Document tree.
class DOMBuilder extends BuilderSupport {
DOMBuilder()
DOMBuilder(DocumentBuilderFactory factory)
Document getDocument()
DocumentBuilderFactory getDocumentBuilderFactory()
void setDocumentBuilderFactory(DocumentBuilderFactory factory)
static Document parse(Reader reader)
static Document parse(Reader reader, boolean validating)
static Document parse(Reader reader, boolean validating, boolean namespaceAware)
static Document parse(File file)
static Document parse(String uri)
static Document parse(InputSource input)
static Document parse(InputStream input)
}SAX-based builder for event-driven XML processing.
class SAXBuilder extends BuilderSupport {
SAXBuilder(ContentHandler handler)
ContentHandler getContentHandler()
void setContentHandler(ContentHandler handler)
}Utility class for common XML operations.
class XmlUtil {
static String serialize(String xmlString)
static String serialize(GPathResult node)
static String serialize(Node node)
static String serialize(Element element)
static String serialize(Document document)
static void serialize(Node node, OutputStream os)
static void serialize(Node node, Writer writer)
static void serialize(GPathResult node, Writer writer)
static String escapeXml(String value)
static String unescapeXml(String value)
static Node asNode(GPathResult gpathResult)
static String asString(Node node)
}Usage examples:
import groovy.xml.XmlUtil
import groovy.util.XmlSlurper
// Serialize XML structures
def xml = '''<book><title>Test</title></book>'''
def slurper = new XmlSlurper()
def book = slurper.parseText(xml)
def serialized = XmlUtil.serialize(book)
println serialized
// Escape/unescape XML
def unsafe = 'Title with <special> & "quoted" text'
def escaped = XmlUtil.escapeXml(unsafe)
def unescaped = XmlUtil.unescapeXml(escaped)
assert unescaped == unsafeSupport for XML namespaces in parsing and generation.
class Namespace {
Namespace(String uri)
Namespace(String uri, String prefix)
String getUri()
String getPrefix()
QName name(String localName)
boolean equals(Object other)
int hashCode()
String toString()
}Usage examples:
import groovy.xml.Namespace
import groovy.xml.MarkupBuilder
// Define namespaces
def xhtml = new Namespace('http://www.w3.org/1999/xhtml', 'h')
def custom = new Namespace('http://example.com/custom', 'c')
// Use in MarkupBuilder
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.'h:html'('xmlns:h': xhtml.uri, 'xmlns:c': custom.uri) {
'h:head' {
'h:title'('Test Document')
}
'h:body' {
'h:p'('This is a paragraph.')
'c:custom-element'(attribute: 'value', 'Custom content')
}
}
// Parse namespaced XML
def namespacedXml = '''
<root xmlns:ns="http://example.com/ns">
<ns:element>Content</ns:element>
</root>
'''
def slurper = new XmlSlurper(false, true) // namespace aware
def root = slurper.parseText(namespacedXml)
def ns = new groovy.xml.Namespace('http://example.com/ns', 'ns')
assert root[ns.element].text() == 'Content'import groovy.util.XmlSlurper
import javax.xml.validation.SchemaFactory
import javax.xml.XMLConstants
// Parse with validation
def schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
def schema = schemaFactory.newSchema(new File('schema.xsd'))
def slurper = new XmlSlurper()
slurper.setProperty('http://java.sun.com/xml/jaxp/properties/schemaLanguage',
XMLConstants.W3C_XML_SCHEMA_NS_URI)
slurper.setProperty('http://java.sun.com/xml/jaxp/properties/schemaSource',
schema)
try {
def result = slurper.parse(new File('document.xml'))
// Process validated XML
} catch (SAXException e) {
println "Validation error: ${e.message}"
}import groovy.util.XmlSlurper
import org.xml.sax.SAXParseException
try {
def slurper = new XmlSlurper()
def result = slurper.parseText('<invalid><xml>') // Malformed XML
} catch (SAXParseException e) {
println "XML parsing error at line ${e.lineNumber}, column ${e.columnNumber}: ${e.message}"
} catch (Exception e) {
println "General error: ${e.message}"
}import org.xml.sax.EntityResolver
import org.xml.sax.InputSource
class CustomEntityResolver implements EntityResolver {
InputSource resolveEntity(String publicId, String systemId) {
if (systemId.endsWith('custom.dtd')) {
return new InputSource(new StringReader('<!ENTITY custom "Custom Entity">'))
}
return null
}
}
def slurper = new XmlSlurper()
slurper.entityResolver = new CustomEntityResolver()// For large XML files, use streaming approach
def processLargeXml(File xmlFile) {
def slurper = new XmlSlurper()
xmlFile.withInputStream { stream ->
def root = slurper.parse(stream)
// Process elements one at a time to minimize memory usage
root.children().each { element ->
processElement(element)
// Clear processed data if possible
}
}
}
// For memory-constrained environments
def slurper = new XmlSlurper(false, false) // Non-validating, non-namespace aware
slurper.setFeature('http://apache.org/xml/features/nonvalidating/load-external-dtd', false)Install with Tessl CLI
npx tessl i tessl/maven-org-codehaus-groovy--groovy-all