使用Kotlin扩展函数和Lambda生成XML

对于移动开发者来说,处理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!

翻译自原文地址

    原文作者:宛丘之上兮
    原文地址: https://www.jianshu.com/p/f6d33aff073b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞