对于移动开发者来说,处理JSON是很轻松的事情。但是有时候我们也需要处理XML来支持陈旧的web服务API。有很多方法来生成XML in android,但是它们看起来都臃肿、易错和过度设计,没有一个令我满意。当我寻求解决方案的时候,我发现了这个文章。这个作者很好地使用Kotlin扩展函数和Lambdas来避免生成XML的代码臃肿。作为一个Kotlin爱好者并且尝试了下,我设计了几个Kotlin扩展函数来生成XML,世界清静了,生活惬意了。
假设我们需要生成的XML如下:
<?xml version="1.0" encoding="UTF-8"?>
<Movies>
<row no="1">
<FL val="TicketId">6000000066015</FL>
<FL val="MovieName">Dunkirk</FL>
<FL val="TimeLog">
<row no="1">
<FL val="date">23/01/2018</FL>
<FL val="startTime">08:00</FL>
</row>
</FL>
</row>
</Movies>
其中一段丑陋、最长、臃肿和易错的代码可以满足需求:
val xmlSerializer = Xml.newSerializer()
val writer = StringWriter()
xmlSerializer.setOutput(writer)
xmlSerializer.startDocument("UTF-8", false)
xmlSerializer.startTag("", "Movies")
xmlSerializer.startTag("", "row")
xmlSerializer.attribute("", "no", "1")
xmlSerializer.startTag("", "FL")
xmlSerializer.attribute("", "val", "TicketId")
xmlSerializer.text("6000000066015")
xmlSerializer.endTag("", "FL")
xmlSerializer.startTag("", "FL")
xmlSerializer.attribute("", "val", "MovieName")
xmlSerializer.text("Dunkirk")
xmlSerializer.endTag("", "FL")
xmlSerializer.startTag("", "FL")
xmlSerializer.attribute("", "val", "TimeLog")
xmlSerializer.startTag("", "row")
xmlSerializer.attribute("", "no", "1")
xmlSerializer.startTag("", "FL")
xmlSerializer.attribute("", "val", "logDate")
xmlSerializer.text("23/01/2018")
xmlSerializer.endTag("", "FL")
xmlSerializer.startTag("", "FL")
xmlSerializer.attribute("", "val", "startTime")
xmlSerializer.text("08:00")
xmlSerializer.endTag("", "FL")
xmlSerializer.endTag("", "row")
xmlSerializer.endTag("", "FL")
xmlSerializer.endTag("", "row")
xmlSerializer.endTag("", "Movies")
xmlSerializer.endDocument()
println(writer.toString())
但是也有一种最简单的、优雅的、易读的代码也能满足需求:
val xmlSerializer = Xml.newSerializer()
val xmlString = xmlSerializer.document {
element("Movies") {
element("row") {
attribute("no", "1")
element("FL", "6000000066015") {
attribute("val", "TicketId")
}
element("FL", "Dunkirk") {
attribute("val", "MovieName")
}
element("FL") {
attribute("val", "TimeLog")
element("row") {
attribute("no", "1")
element("FL", "23/01/2018") {
attribute("val", "date")
}
element("FL", "08:00") {
attribute("val", "startTime")
}
}
}
}
}
}
println(xmlString)
上面代码使用到的扩展函数代码:
// XML generation by code
fun XmlSerializer.document(docName: String = "UTF-8",
xmlStringWriter: StringWriter = StringWriter(),
init: XmlSerializer.() -> Unit): String {
startDocument(docName, true)
xmlStringWriter.buffer.setLength(0) // refreshing string writer due to reuse
setOutput(xmlStringWriter)
init()
endDocument()
return xmlStringWriter.toString()
}
// element
fun XmlSerializer.element(name: String, init: XmlSerializer.() -> Unit) {
startTag("", name)
init()
endTag("", name)
}
// element with attribute & content
fun XmlSerializer.element(name: String,
content: String,
init: XmlSerializer.() -> Unit) {
startTag("", name)
init()
text(content)
endTag("", name)
}
// element with content
fun XmlSerializer.element(name: String, content: String) =
element(name) {
text(content)
}
// attribute
fun XmlSerializer.attribute(name: String, value: String) =
attribute("", name, value)
好啦,就这么多! 请查看我的代码地址获取更多信息。
Happy Coding!
翻译自原文地址
网友评论