这篇会讲解怎麽样用 DOM 的 parser 把 RSS 资讯拿出来,首先我们可以先 new 一个 DocumentBuilder
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
接着把 XML 字串塞进去 builder
里,塞之前我们要先转成 ByteArrayInputStream
,就可以拿到一个 document 。
val document = builder.parse(xml.byteInputStream())
我们可以从 document 里面拿到指定 tag 的节点列表,下方就是拿 <channel>
底下的子节点列表。
const val CHANNEL = "channel"
val nodeList = document.getElementsByTagName(CHANNEL)
拿到节点列表之後我们就可以对节点做操作了!但这边因为 RSS 格式中预设只有一个 <channel>
所以我们可以写一个 parserChannel
的 function 。从 nodeList 拿出来的 node 要转型成 Element
才可以进行操作。这个 function 的第二个参数 action
是一个 lambda ,让使用者决定拿到 channel 的 element 後要进行的动作。
inline fun <T> parseChannel(xml: String, action: Element.() -> T): T {
val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder()
val document = builder.parse(xml.byteInputStream())
document.documentElement.normalize()
val nodeList = document.getElementsByTagName(CHANNEL)
var result: T? = null
if (nodeList?.length == 1) {
val element = nodeList.item(0) as? Element
element?.let {
result = action(it)
}
}
return result ?: throw IllegalArgumentException("No valid channel tag in the RSS feed.")
}
前一篇的文章有提到 DOM parser 有个特色就是可以跨层查询,但我们怎麽指定我们要查询哪一个 tag 底下的值?其实可以透过指定 parent tag 的方式去查找。这是为了解决一个可能遇到的问题:假如我们今天要找 <channel>
tag 底下的 <title>
,这个 title 可能存在於 <channel>
底下,但也可能存在於 <image>
底下。
<channel>
<title>channel title</title>
<image>
<link>http://channel.image.link</link>
<title>channel image title</title>
</image>
</channel>
为了解决上面情境发生的问题,我可以写一个 Element
的 extension function ,让我们可以取某个 tag 的值出来,但可以指定 parent 的 tag name 。
fun Element.readString(name: String, parentTag: String? = null): String? {
val nodeList = getElementsByTagName(name)
if (parentTag == null) {
return nodeList.item(0)?.textContent
} else {
for (i in 0 until nodeList.length) {
val e = nodeList.item(i) as? Element ?: continue
val parent = e.parentNode as? DeferredElementImpl
if (parent?.tagName != parentTag) continue
return e.textContent
}
return null
}
}
>>: @Day8 | C# WixToolset + WPF 帅到不行的安装包 [自订动作]
RealmSwift是一款非常好用的第三方资料库,但安装RealmSwift之前,我们必须先安装Co...
MVP架构: Model — 管理资料来源。例如:SharedPreferences、Room、呼叫...
敏捷 敏捷心态(AGILE MINDSET) 敏捷是一种由价值观,原则和实践组成的心态。满足敏捷思维...
今晚参与了"MakerPro社群媒体平台"举办的 在MCU 上全面建构AI能力 ...
今年的 DevFest Hsinchu & Taichung 已经在上周六顺利结束了!感谢 ...