美文网首页Android开发Android开发经验谈Android开发
使用Kotlin扩展函数和Lambda生成XML

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

作者: 宛丘之上兮 | 来源:发表于2018-03-05 18:45 被阅读55次

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


    翻译自原文地址

    相关文章

      网友评论

        本文标题:使用Kotlin扩展函数和Lambda生成XML

        本文链接:https://www.haomeiwen.com/subject/olohfftx.html