Working with XML in Kotlin: Overview of Libraries and Practical Examples
Despite the active adoption of JSON and YAML, XML remains a popular format in enterprise systems, configuration files, SOAP protocols, and Android development. Kotlin, being compatible with Java, provides access to all mature Java libraries for working with XML, as well as having its own native solutions. In this article, we will cover five main approaches to XML processing in Kotlin, including parsing, creation, and validation of documents.
1. Built-in Tools: DOM, SAX, StAX
Kotlin directly uses the standard Java API for XML. This is the simplest way for quick tasks, but it requires a lot of boilerplate code.
DOM (Document Object Model)
Loads the entire XML into memory and allows random access to nodes. Suitable for small documents.
import javax.xml.parsers.DocumentBuilderFactoryimport org.w3c.dom.Element
fun parseWithDOM(xml: String) { val factory = DocumentBuilderFactory.newInstance() val builder = factory.newDocumentBuilder() val doc = builder.parse(xml.byteInputStream()) val books = doc.getElementsByTagName("book") for (i in 0 until books.length) { val book = books.item(i) as Element val title = book.getElementsByTagName("title").item(0).textContent println("Book: $title") }}SAX (Simple API for XML)
A streaming parser that does not load the entire document into memory. Efficient for large files, but complex to implement.
import org.xml.sax.helpers.DefaultHandlerimport org.xml.sax.Attributesimport javax.xml.parsers.SAXParserFactory
class BookHandler : DefaultHandler() { override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) { if (qName == "book") { println("Found book with id: ${attributes.getValue("id")}") } }}
fun parseWithSAX(xml: String) { val factory = SAXParserFactory.newInstance() val parser = factory.newSAXParser() parser.parse(xml.byteInputStream(), BookHandler())}2. JDOM — Convenient API for Kotlin
JDOM is a popular Java library that integrates well with Kotlin thanks to support for collections and extension functions. It allows reading, modifying, and creating XML without cumbersome factories.
Parsing and Navigation
import org.jdom2.input.SAXBuilderimport org.jdom2.Element
fun parseWithJDOM(xml: String) { val builder = SAXBuilder() val doc = builder.build(xml.byteInputStream()) val root = doc.rootElement root.getChildren("book").forEach { book -> val title = book.getChildText("title") val author = book.getChildText("author") println("$title — $author") }}Creating XML from Scratch
import org.jdom2.Documentimport org.jdom2.Elementimport org.jdom2.output.XMLOutputter
fun createXML(): String { val root = Element("library") val book = Element("book").apply { setAttribute("id", "1") addContent(Element("title").setText("Kotlin in Action")) addContent(Element("author").setText("Dmitry Jemerov")) } root.addContent(book) val doc = Document(root) val outputter = XMLOutputter().apply { format = org.jdom2.output.Format.getPrettyFormat() } return outputter.outputString(doc)}3. XOM — Simplicity and Strictness
XOM adheres to the principle of "immutable by default" — once created, nodes cannot be modified, only replaced. This makes the code predictable and safe. The library automatically checks the correctness of the structure.
import nu.xom.Builderimport nu.xom.Serializer
fun parseWithXOM(xml: String) { val builder = Builder() val doc = builder.build(xml, null) val root = doc.rootElement Also in library
Working with YAML in C# (.NET): Libraries and Usage Examples
Working with S3 and Cloud Storage in Kotlin: AWS SDK and MinIO