在没有 'case class' 的情况下在 Scala 中阅读 YAML
Reading YAML in Scala without 'case class'
我正在尝试从 Scala
读取 YAML
文件,并且我能够使用下面给出的代码读取该文件。我在这里看到的缺点之一是我必须创建 case class
才能与我正在使用的 YAML
文件进行映射。每次我更改 YAML
的内容时,我都必须更改 case class
。在 Scala 中有没有什么方法可以读取 YAML
而无需 我需要创建 case class
。 (我还使用 Python
来阅读 YAML
;我们没有将 Class
映射到 YAML
结构的约束......并且想做类似的事情Scala
)
中的内容
注意 :当我在 YAML
中添加一个新的 属性 并且如果我的 case class
没有匹配的 属性 我得到 UnrecognizedPropertyException
package yamlexamples
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object YamlTest extends App{
case class Prop(country: String, state: List[String])
val mapper: ObjectMapper = new ObjectMapper(new YAMLFactory())
mapper.registerModule(DefaultScalaModule)
val fileStream = getClass.getResourceAsStream("/sample.yaml")
val prop:Prop = mapper.readValue(fileStream, classOf[Prop])
println(prop.country + ", " + prop.state)
}
sample.yaml
(这适用于代码)
country: US
state:
- TX
- VA
sample.yaml
(抛出异常)
country: US
state:
- TX
- VA
continent: North America
您可以解析 Yaml 文件并将其加载为集合对象而不是 case case。但这是以失去代码中的类型安全为代价的。下面的代码使用 Yaml
支持的 load
函数。请注意 load
也有 overloaded methods 可以从 inputstream/reader 中读取..
import scala.collection.JavaConverters._
val yaml = new Yaml()
val data = yaml.load(
"""
|country: US
|state:
| - TX
| - VA
|continent: North America
""".stripMargin).asInstanceOf[java.util.Map[String, Any]].asScala
现在数据是一个 scala 可变集合而不是一个案例 class
data: scala.collection.mutable.Map[String,Any] = Map(country -> US, state -> [TX, VA], continent -> North America)
您可以使用 Jackson 或 SnakeYaml 解析 YAML 文件。但是,Jackson 不支持 references/anchors,而 SnakeYaml 支持。因此,最好使用 SnakeYaml 解析 YAML 文件并使用 Jackson 库访问数据元素
import java.io.{File, FileInputStream, FileReader}
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}
import org.yaml.snakeyaml.Yaml
// Parsing the YAML file with SnakeYAML - since Jackson Parser does not support Anchors and references
val ios = new FileInputStream(new File(yamlFilePath))
val yaml = new Yaml()
val mapper = new ObjectMapper().registerModules(DefaultScalaModule)
val yamlObj = yaml.loadAs(ios, classOf[Any])
// Converting the YAML to Jackson YAML - since it has more flexibility
val jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(yamlObj) // Formats YAML to a pretty printed JSON string - easy to read
val jsonObj = mapper.readTree(jsonString)
最后,你得到了 JsonNode 对象,它使我们能够转换为其他数据类型。
我正在尝试从 Scala
读取 YAML
文件,并且我能够使用下面给出的代码读取该文件。我在这里看到的缺点之一是我必须创建 case class
才能与我正在使用的 YAML
文件进行映射。每次我更改 YAML
的内容时,我都必须更改 case class
。在 Scala 中有没有什么方法可以读取 YAML
而无需 我需要创建 case class
。 (我还使用 Python
来阅读 YAML
;我们没有将 Class
映射到 YAML
结构的约束......并且想做类似的事情Scala
)
注意 :当我在 YAML
中添加一个新的 属性 并且如果我的 case class
没有匹配的 属性 我得到 UnrecognizedPropertyException
package yamlexamples
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object YamlTest extends App{
case class Prop(country: String, state: List[String])
val mapper: ObjectMapper = new ObjectMapper(new YAMLFactory())
mapper.registerModule(DefaultScalaModule)
val fileStream = getClass.getResourceAsStream("/sample.yaml")
val prop:Prop = mapper.readValue(fileStream, classOf[Prop])
println(prop.country + ", " + prop.state)
}
sample.yaml
(这适用于代码)
country: US
state:
- TX
- VA
sample.yaml
(抛出异常)
country: US
state:
- TX
- VA
continent: North America
您可以解析 Yaml 文件并将其加载为集合对象而不是 case case。但这是以失去代码中的类型安全为代价的。下面的代码使用 Yaml
支持的 load
函数。请注意 load
也有 overloaded methods 可以从 inputstream/reader 中读取..
import scala.collection.JavaConverters._
val yaml = new Yaml()
val data = yaml.load(
"""
|country: US
|state:
| - TX
| - VA
|continent: North America
""".stripMargin).asInstanceOf[java.util.Map[String, Any]].asScala
现在数据是一个 scala 可变集合而不是一个案例 class
data: scala.collection.mutable.Map[String,Any] = Map(country -> US, state -> [TX, VA], continent -> North America)
您可以使用 Jackson 或 SnakeYaml 解析 YAML 文件。但是,Jackson 不支持 references/anchors,而 SnakeYaml 支持。因此,最好使用 SnakeYaml 解析 YAML 文件并使用 Jackson 库访问数据元素
import java.io.{File, FileInputStream, FileReader}
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper}
import org.yaml.snakeyaml.Yaml
// Parsing the YAML file with SnakeYAML - since Jackson Parser does not support Anchors and references
val ios = new FileInputStream(new File(yamlFilePath))
val yaml = new Yaml()
val mapper = new ObjectMapper().registerModules(DefaultScalaModule)
val yamlObj = yaml.loadAs(ios, classOf[Any])
// Converting the YAML to Jackson YAML - since it has more flexibility
val jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(yamlObj) // Formats YAML to a pretty printed JSON string - easy to read
val jsonObj = mapper.readTree(jsonString)
最后,你得到了 JsonNode 对象,它使我们能够转换为其他数据类型。