在 Kotlin 中处理 XML:库、解析与文档创建
XML(可扩展标记语言)仍然是存储和传输结构化数据的流行格式,尤其是在遗留系统、配置文件和 Web 服务中。Kotlin 与 Java 完全兼容,因此可以访问所有经典的 Java XML 处理库,同时也拥有原生解决方案。在本文中,我们将介绍主要方法:在 Kotlin 中解析、创建和序列化 XML 文档。
1. JDK 内置工具:DOM、SAX、StAX
由于与 Java 完全互操作,Kotlin 可以直接使用标准 API:
- DOM(文档对象模型) — 将整个文档加载到内存中,便于修改。
- SAX(XML 简单 API) — 事件驱动的解析器,内存占用最小。
- StAX(XML 流式 API) — 流式解析器,支持游标或事件方式。
在 Kotlin 中使用 DOM 解析 XML 的示例:
import javax.xml.parsers.DocumentBuilderFactoryimport org.w3c.dom.Element
fun parseXmlWithDom(xmlString: String) { val factory = DocumentBuilderFactory.newInstance() val builder = factory.newDocumentBuilder() val document = builder.parse(xmlString.byteInputStream()) val root = document.documentElement
val items = root.getElementsByTagName("item") for (i in 0 until items.length) { val item = items.item(i) as Element val name = item.getElementsByTagName("name").item(0).textContent val price = item.getElementsByTagName("price").item(0).textContent println("Item: $name, Price: $price") }}2. Simple XML 库 (org.simpleframework.xml)
Simple XML 是一个流行的用于对象与 XML 之间序列化/反序列化的库。它使用注解,无需配置文件。非常适合处理 XML 响应的 REST API。
依赖配置 (Gradle):
implementation("org.simpleframework:simple-xml:2.7.1")模型与反序列化示例:
import org.simpleframework.xml.*import org.simpleframework.xml.core.Persister
@Root(name = "catalog")data class Catalog( @field:ElementList(inline = true) var books: List<Book> = emptyList())
@Root(name = "book")data class Book( @field:Element(name = "title") var title: String = "", @field:Element(name = "author") var author: String = "", @field:Attribute(name = "id") var id: Int = 0)
fun deserializeXml(xml: String): Catalog { val serializer = Persister() return serializer.read(Catalog::class.java, xml)}3. kotlinx.serialization 与 XML 格式
对于多平台项目 (KMP),使用 kotlinx.serialization 配合自定义 XML 格式非常方便。存在第三方适配器,例如 kotlinx-serialization-xml(来自社区)。
使用 nl.adaptivity.xmlutil 库的示例(支持 JVM、JS、Native):
import nl.adaptivity.xmlutil.serialization.XMLimport kotlinx.serialization.*
@Serializabledata class Person( val name: String, @XmlSerialName("age") val years: Int)
fun main() { val xml = XML { indent = 4 xmlDeclMode = XmlDeclMode.Auto } val person = Person("Alice", 30) val result = xml.encodeToString(Person.serializer(), person) println(result) // <Person> // <name>Alice</name> // <age>30</age> // </Person>}4. Kotlin 中的 XPath 和 XSLT
要根据复杂条件提取数据,请使用 XPath。在 Kotlin 中,这通过标准 Java 类 javax.xml.xpath 实现。