JavaVM で XML を扱う場合に XmlPullParser を使う例を このエントリーXmlPullParser を使ってXMLをパースする で書きました。 今度はこれと同じような処理を Kotlin Native でやってみたので備忘録としてそれを書き残します。 XmlPullParser の代りに XmlUtilを使います。
そういえば、XmlUtil を使った例は以前のエントリー Kotlin Native (linuxX64) で XML を扱うで書きました。ここではシリアライゼーションしないで、 直接 XML をパースします。
Gradle で Kotlin Native するには: https://kotlinlang.org/docs/native-gradle.html
$ java -version
openjdk version "17.0.10" 2024-01-16
OpenJDK Runtime Environment (build 17.0.10+7-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 17.0.10+7-Ubuntu-122.04.1, mixed mode, sharing)
$ gradle -version
Gradle 8.4
OS は Ubuntu 22.04 LTS です。
$ mkdir hello-xml
$ cd hello-xml
$ touch build.gradle.kts
$ touch settings.gradle
$ touch gradle.properties
build.gradle.kts の内容:
plugins {
kotlin("multiplatform") version "1.9.23"
}
version = "0.1"
repositories {
mavenCentral()
}
kotlin {
// macosX64("native") { // on macOS
// mingwX64("native") { // on Windows
linuxX64("native") { // on Linux
binaries {
executable()
}
}
sourceSets {
nativeMain {
dependencies {
implementation("io.github.pdvrieze.xmlutil:core:0.86.3")
}
}
}
}
tasks.withType<Wrapper> {
gradleVersion = "8.4"
distributionType = Wrapper.DistributionType.BIN
}
settings.gradle ファイルを用意して次の内容を記述します。
rootProject.name = "hello"
今回は hello.kexe というファイル名でバイナリを生成したいので rootProject.name に hello を設定しました。
gradle.properties ファイルを用意して次の内容を記述します。
kotlin.mpp.applyDefaultHierarchyTemplate=false
続いて App.kt の用意:
$ mkdir -p src/nativeMain/kotlin/
$ touch src/nativeMain/kotlin/App.kt
src/nativeMain/kotlin/App.kt:
import nl.adaptivity.xmlutil.XmlReader
import nl.adaptivity.xmlutil.xmlStreaming
import nl.adaptivity.xmlutil.EventType
fun main() {
val text = "<html><body><p>Hello, World!</p></body></html>"
val xr: XmlReader = xmlStreaming.newReader(text)
var eventType: EventType = xr.next()
while( eventType != EventType.END_DOCUMENT ){
when(eventType){
EventType.START_DOCUMENT -> println("Start Document")
EventType.START_ELEMENT -> println("Start Element: ${xr.name}")
EventType.END_ELEMENT -> println("End Element: ${xr.name}")
EventType.TEXT -> println("Text: ${xr.text}")
else -> {
println("Unknown EventType: ${eventType}")
}
}
eventType = xr.next()
}
}
おおむね前回のエントリーのコードと同じです。
ここで実行して作動を確かめます。
$ gradle runDebugExecutableNative
> Task :runDebugExecutableNative
Start Document
Start Element: html
Start Element: body
Start Element: p
Text: Hello, World!
End Element: p
End Element: body
End Element: html
必要であれば gradle wrapper しておきましょう。
$ gradle wrapper
あとは while している部分を再帰関数に書きかえてもよいのですが、 前回と同じ話を繰り返すだけなので省略します。
もし属性をパースする場合は次のように記述します(抜粋)。
EventType.START_ELEMENT -> {
val attrs = 0.until(xr.attributeCount).map { index->
val name = xr.getAttributeName(index)
val value = xr.getAttributeValue(index)
"$name=$value"
}.joinToString(",")
println("${xr.name}, ${attrs})")
}
Linux(X64) 用のNativeバイナリ実行ファイルを生成するには nativeBinaries タスクを使用。
$ ./gradlew nativeBinaries
次の場所にそれが生成されます: ./build/bin/native/releaseExecutable/hello.kexe
以上です。