Home About Contact
Kotlin , Kotlin Native , Gradle

Kotlin Native (linuxX64) で XML を扱う

Kotlin Native (Kotlin Multiplatform) で XMLを扱うにはどうすればよいか調べた。 XmlUtilを使えばよいらしい。 Gradle を使って、XmlUtil で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 です。

hello-linux プロジェクト

$ mkdir hello-linux
$ cd hello-linux
$ touch build.gradle.kts

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()
        }
    }
}

続いて App.kt の用意:

$ mkdir -p src/nativeMain/kotlin/
$ touch src/nativeMain/kotlin/App.kt

kotlin js の場合は nativeMainjsMain にしていた。 (see : Kotlin Multiplatform 1.9.22 Kotlin/JS Hello, World!)

src/nativeMain/kotlin/App.kt:

fun main() {
    println("Hello, World!")
}    

ここで実行して作動を確かめます。

$ gradle build

エラーがなければ gradle wrapper しておきましょう。

$ gradle wrapper

以後は、 gradle に代えて ./gradlew を使っていきます。

それでは実行します。

$ ./gradlew runDebugExecutableNative

> Task :runDebugExecutableNative
Hello, World!

実際は次のようなメッセージが出た。

Consider renaming the targets or disabling the default template by adding
    'kotlin.mpp.applyDefaultHierarchyTemplate=false'
to your gradle.properties

Learn more about hierarchy templates: https://kotl.in/hierarchy-template

このメッセージを消すには、このメッセージの助言通りに gradle.properties ファイルを作成して次の設定を記述しておく。

kotlin.mpp.applyDefaultHierarchyTemplate=false

XmlUtil を使う

App.kt に XmlUtil のコードを入れます。

src/nativeMain/kotlin/App.kt:

import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.serialization.XML

@Serializable
data class HelloWorld(val user: String)

fun main() {
    println("Hello, World!")

    println(XML.encodeToString(HelloWorld("You!")))

    val hw = XML.decodeFromString(HelloWorld.serializer(), "<HelloWorld user='You!' />")
    println( hw )
}

このコードをビルドできるように build.gradle.kts に次の変更を入れます。

@@ -1,5 +1,6 @@
 plugins {
     kotlin("multiplatform") version "1.9.23"
+    kotlin("plugin.serialization") version "1.9.23"
 }

 version = "0.1"
@@ -16,4 +17,13 @@ kotlin {
             executable()
         }
     }
+
+    sourceSets {
+         nativeMain {
+            dependencies {
+                implementation("io.github.pdvrieze.xmlutil:core:0.86.3")
+                implementation("io.github.pdvrieze.xmlutil:serialization:0.86.3")
+            }
+        }
+    }
 }

plugin に serialization を入れて、依存に xmlutil のライブラリを追加しました。

実行します。

$ ./gradlew runDebugExecutableNative

> Task :runDebugExecutableNative
Hello, World!
<HelloWorld user="You!" />
HelloWorld(user=You!)

XMLデータをファイルから読み込んでデシリアライズ

以前のエントリーで Kotlin Native でテキストファイルを読むことを試していました。 それとこの XmlUtil をいっしょに使ってみます。

see: native-file-io

hello.txt を作成:

<HelloWorld user='You!' />

App.kt を修正:

import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.serialization.XML
import me.archinamon.fileio.File
import me.archinamon.fileio.readText

@Serializable
data class HelloWorld(val user: String)

fun main() {
    val helloFile = File("hello.txt")
    if( helloFile.exists() ){
        val text = helloFile.readText()
        print("${text}")

        val hw = XML.decodeFromString(HelloWorld.serializer(), text)
        println( hw )
    }
}

hello.txt を読み込みそのテキストを decodeFromString して結果を標準出力しています。

ファイルを扱うライブラリの記述を build.gradle.kts に追加:

@@ -23,6 +23,8 @@ kotlin {
             dependencies {
                 implementation("io.github.pdvrieze.xmlutil:core:0.86.3")
                 implementation("io.github.pdvrieze.xmlutil:serialization:0.86.3")
+                implementation("me.archinamon:file-io:1.3.4")
+                implementation("me.archinamon:file-io-linuxx64:1.3.4")
             }
         }
     }

実行してみます。

$ ./gradlew runDebugExecutableNative

> Task :runDebugExecutableNative
<HelloWorld user='You!' />
HelloWorld(user=You!)

作動しました。

まとめ

これで Kotlin Native を使ってファイルからXMLデータを読み込んで処理できるようになりました。