■ はじめに
Scala で YAMLファイルを扱う方法を扱う
目次
【1】YAML用ライブラリ「org.yaml.snakeyaml.Yaml」 1)設定 2)API仕様 【2】サンプル 例1:Hello World 例2:独自クラスにマッピングする 例3:別YAML&リファクタリング
【1】YAML用ライブラリ「org.yaml.snakeyaml.Yaml」
* YAML用ライブラリとして「org.yaml.snakeyaml.Yaml」を使用 => 詳細は、以下を参照
https://javadoc.io/static/org.yaml/snakeyaml/1.19/org/yaml/snakeyaml/Yaml.html
https://javadoc.io/static/org.yaml/snakeyaml/2.0/org/yaml/snakeyaml/Yaml.html
1)設定
* 使用には、libraryDependencies への追加が必要。
build.sbt
libraryDependencies ++= Seq( "org.yaml" % "snakeyaml" % "1.16" )
https://mvnrepository.com/artifact/org.yaml/snakeyaml
2)API仕様
* 以下を参照
https://javadoc.io/static/org.yaml/snakeyaml/1.19/org/yaml/snakeyaml/Yaml.html
【2】サンプル
「例2:独自クラスにマッピングする」「例3:別YAML&リファクタリング」 を汎用的に独自クラスをマッピングする実装は、以下の関連記事を参照
https://dk521123.hatenablog.com/entry/2023/03/21/003817
例1:Hello World
input.yaml
names: - abc - def age: 10
Main.scala
import org.yaml.snakeyaml.Yaml import java.io.{File, FileInputStream} import scala.jdk.CollectionConverters._ object Main { val yaml = new Yaml val input = new FileInputStream(new File("input.yaml")) val inputData = yaml.load(input) val data = inputData.asInstanceOf[java.util.Map[String, Any]] print(data.toString) val map = data.asScala print(map.get("names")) print(map.get("age")) for(value <- map) { print(value) } }
例2:独自クラスにマッピングする
https://alvinalexander.com/scala/how-to-read-yaml-configuration-file-in-scala/
を参考にしたが 「import scala.reflect.BeanProperty」⇒「import scala.beans.BeanProperty」 にしないと動かなかった。
user.yaml
id: 100 name: Mike hobbies: - "running" - "programming" - "football" skills: "Rust": null "Python": True
Main.scala
import org.yaml.snakeyaml.Yaml import org.yaml.snakeyaml.constructor.Constructor import scala.collection.mutable.ListBuffer import scala.beans.BeanProperty import java.io.{File, FileInputStream} object Main extends App { val input = new FileInputStream(new File("user.yaml")) val inputYaml = new Yaml(new Constructor(classOf[User])) // val user = inputYaml.load(input).asInstanceOf[User] val user = inputYaml.loadAs(input, classOf[User]) // id: 100, name: Mike, hobbies: [running, programming, football], skills: {Rust=null, Python=true} println(user) } class User { @BeanProperty var id = -1 @BeanProperty var name = "" @BeanProperty var hobbies = new java.util.ArrayList[String]() @BeanProperty var skills = new java.util.HashMap[String, Any]() override def toString: String = s"id: $id, name: $name, hobbies: $hobbies, skills: $skills" }
例3:別YAML&リファクタリング
process_info.yaml
processName: processA schedule: 10:00-12:00 emailListToNotify: - sample@gmail - sample@yahoo.com subProcesses: sub-processA1: inputPath: s3://your-bucket/sub-processA1/input/ outputPath: s3://your-bucket/sub-processA1/output/ sub-processA2: inputPath: s3://your-bucket/sub-processA2/input/ outputPath: s3://your-bucket/sub-processA2/output/ sub-processA3: inputPath: s3://your-bucket/sub-processA3/input/ outputPath: s3://your-bucket/sub-processA3/output/
Main.scala
import org.yaml.snakeyaml.Yaml import org.yaml.snakeyaml.constructor.Constructor import scala.collection.mutable.ListBuffer import scala.beans.BeanProperty import java.io.{File, FileInputStream} import scala.util.Using object Main extends App { val inputPath = raw"C:\work\scala\codes\HelloWorld\thisismyfirsttime\src\main\scala\process_info.yaml" val processInfo = readYaml(inputPath) println(processInfo) def readYaml(inputPath: String): ProcessInfo = { var returnValue: ProcessInfo = new ProcessInfo Using(new FileInputStream(new File(inputPath))) { reader => val inputYaml = new Yaml(new Constructor(classOf[ProcessInfo])) returnValue = inputYaml.loadAs(reader, classOf[ProcessInfo]) } return returnValue } } class ProcessInfo { @BeanProperty var processName = "" @BeanProperty var schedule = "" @BeanProperty var emailListToNotify = new java.util.ArrayList[String]() @BeanProperty var subProcesses = new java.util.HashMap[String, java.util.HashMap[String, Any]]() override def toString: String = s"processName : $processName , schedule: $schedule, emailListToNotify : $emailListToNotify , subProcesses : $subProcesses " }
補足
* Usingなどのファイルハンドリング関連については、 以下の関連記事を参照のこと
Scala ~ ファイルハンドリング ~
https://dk521123.hatenablog.com/entry/2023/01/03/000000
参考文献
https://qiita.com/toastkidjp/items/66ddd8daa3c625afc351
https://www.qoosky.io/techs/66d656fb42
https://alvinalexander.com/scala/how-to-read-yaml-configuration-file-in-scala/
https://www.task-notes.com/entry/20150923/1442977200
関連記事
Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ 基本編 / クラス ~
https://dk521123.hatenablog.com/entry/2023/03/14/000857
Scala ~ 基本編 / ジェネリック
https://dk521123.hatenablog.com/entry/2023/03/21/003817
Scala ~ ファイルハンドリング ~
https://dk521123.hatenablog.com/entry/2023/01/03/000000
Scala ~ JSON ~
https://dk521123.hatenablog.com/entry/2023/04/04/000733