Работа с XML в Kotlin: обзор библиотек и практические примеры
Несмотря на активное внедрение JSON и YAML, XML остаётся востребованным форматом в корпоративных системах, конфигурационных файлах, протоколах SOAP и Android-разработке. Kotlin, будучи совместимым с Java, предоставляет доступ ко всем зрелым Java-библиотекам для работы с XML, а также имеет собственные нативные решения. В этой статье мы разберём пять основных подходов к обработке XML в Kotlin, включая парсинг, создание и валидацию документов.
1. Встроенные средства: DOM, SAX, StAX
Kotlin напрямую использует стандартный Java API для XML. Это самый простой способ для быстрых задач, но он требует много шаблонного кода.
DOM (Document Object Model)
Загружает весь XML в память и позволяет произвольный доступ к узлам. Подходит для небольших документов.
import javax.xml.parsers.DocumentBuilderFactory
import 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("Книга: $title")
}
}
SAX (Simple API for XML)
Потоковый парсер, не загружает весь документ в память. Эффективен для больших файлов, но сложен в реализации.
import org.xml.sax.helpers.DefaultHandler
import org.xml.sax.Attributes
import javax.xml.parsers.SAXParserFactory
class BookHandler : DefaultHandler() {
override fun startElement(uri: String, localName: String, qName: String, attributes: Attributes) {
if (qName == "book") {
println("Найдена книга с id: ${attributes.getValue("id")}")
}
}
}
fun parseWithSAX(xml: String) {
val factory = SAXParserFactory.newInstance()
val parser = factory.newSAXParser()
parser.parse(xml.byteInputStream(), BookHandler())
}
2. JDOM — удобный API для Kotlin
JDOM — популярная Java-библиотека, которая отлично интегрируется с Kotlin благодаря поддержке коллекций и extension-функций. Позволяет читать, модифицировать и создавать XML без громоздких фабрик.
Парсинг и навигация
import org.jdom2.input.SAXBuilder
import 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")
}
}
Создание XML с нуля
import org.jdom2.Document
import org.jdom2.Element
import 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 — простота и строгость
XOM придерживается принципа "immutable by default" — все узлы после создания нельзя изменить, только заменить. Это делает код предсказуемым и безопасным. Библиотека автоматически проверяет корректность структуры.
import nu.xom.Builder
import nu.xom.Serializer
fun parseWithXOM(xml: String) {
val builder = Builder()
val doc = builder.build(xml, null)
val root = doc.rootElement
val books = root.getChildElements("book")
for (i in 0 until books.size) {
val book = books.get(i)
val title = book.getFirstChildElement("title").value
println("Книга: $title")
}
}
fun createWithXOM(): String {
val root = nu.xom.Element("library")
val book = nu.xom.Element("book")
book.addAttribute(nu.xom.Attribute("id", "1"))
val title = nu.xom.Element("title")
title.appendChild("Kotlin in Action")
book.appendChild(title)
root.appendChild(book)
val doc = nu.xom.Document(root)
val serializer = Serializer(System.out, "UTF-8")
serializer.write(doc)
}
4. SimpleXML — аннотационный парсинг
SimpleXML позволяет десериализовать XML напрямую в data-классы Kotlin с помощью аннотаций. Идеально для REST API на основе
Также в библиотеке
Elasticsearch клиент для TypeScript: @elastic/elasticsearch
Swagger/OpenAPI генерация для TypeScript: библиотеки и инструменты
Spring WebFlux для Java: полное руководство с примерами
Геолокация и карты в Swift: CoreLocation и MapKit для iOS/macOS
NodaTime для C# (.NET): полное руководство с примерами