我们现在有了许多的基础的 parser function 了,我们直接来看怎麽样组合这些 function 来 parse 一些东西吧!以 library 里面的 Android parser 为例,我们的目标是拿到 RSS 2.0 标准格式里的 channel 资料。首先,我们先定义 channel 长的样子包在一个 data class 里面,而这个 data class 叫做 RssStandardChannelData
,完整的 data class 可以参考这个连结,这边就不把完整程序码贴上来了。Channel 里面又有包含一些资料,我们就可以定义在另一个 data class 里面,像是 category 、 item 和 cloud 等等。
接着,我们就可以来写 channel 的 parser function 。
@Throws(IOException::class, XmlPullParserException::class)
private fun XmlPullParser.readRssStandardChannel(): RssStandardChannelData {
require(XmlPullParser.START_TAG, null, CHANNEL)
// 1
var title: String? = null
var image: Image? = null
val categories = mutableListOf<Category>()
var cloud: Cloud? = null
var textInput: TextInput? = null
var skipHours: List<Int>? = null
val items = mutableListOf<RssStandardItemData>()
// 省略其他变数宣告
// 2
while (next() != XmlPullParser.END_TAG) {
if (eventType != XmlPullParser.START_TAG) continue
// 3
when (name) {
TITLE -> title = readString(TITLE)
IMAGE -> image = readImage()
CATEGORY -> categories.add(readCategory())
CLOUD -> cloud = readCloud()
TTL -> ttl = readString(TTL)?.toIntOrNull()
RATING -> rating = readString(RATING)
TEXT_INPUT -> textInput = readTextInput()
SKIP_HOURS -> skipHours = readSkipHours()
ITEM -> items.add(readRssStandardItem())
// 省略其他处理
else -> skip()
}
}
require(XmlPullParser.END_TAG, null, CHANNEL)
// 4
return RssStandardChannelData(...)
}
在这个 function 里,我把他分成四个部分来讲解,分别对应上方程序码注解上的数字:
readString
之後再转成想要的型别。如果 tag 还有另一个 tag ,可以再额外定义一个 data class 来代表该子 tag 。如果 tag 名称不在处理的范围,则可以呼叫 skip 去跳过该 tag 。在处理的过程中,有呼叫一些其他的 function ,像是 readCategory readTextInput readSkipHours 和 readRssStandardItem 等,它们内部处理的逻辑是和 readRssStandardChannel 相同,这些 function 可以在这边找到。现在,我们掌握了使用原生的 XmlPullParser 的方法,可以组合出我们想要的资料 parser ,但别高兴得太早!上一段程序码是不是看起来有哪边怪怪的?假设我们有很多种的资料型态和 tag 要取资料,那我们不就要每一种都写一个 function 去处理?如果我们有方法可以去产生这些程序码,我们不用自己手动写。这个就是我们的 annotation processor 可以办得到的事,下篇开始会讲 annotation 和 annotation processor !
<<: Day11- pandas(6)DataFrame有效率的检视资料方法
1.JS是什麽? Java Script 是一种运行在客户端的脚本语言 (script就是脚本的意思...
上一篇的未完成品: 先前按钮的宽度为固定值,所以不会依据视窗的宽度排排站好。修改如下: 按钮的间距保...
哈罗大家好~ 昨天介绍了 Microsoft Power Virtual Agents 智慧虚拟助理...
今天介绍 JS 内 var 与 let 的後两点差异。 执行环境 Execution Context...
今天到嘉义开店 从高雄坐火车到嘉义 在坐火车的一个小时 把外国教python flask的影片看完 ...