我正在尝试从YAML
读取Scala
文件,我可以使用下面给出的代码读取该文件。我在这里看到的一个缺点是我必须创建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
答案 0 :(得分:2)
您可以解析Yaml文件并将其作为集合对象加载而不是大小写。但这是以在代码中丢失类型安全为代价的。以下代码使用load
支持的Yaml
函数。请注意,load
还有overloaded methods来读取输入流/阅读器。
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可变集合而不是案例类
data: scala.collection.mutable.Map[String,Any] = Map(country -> US, state -> [TX, VA], continent -> North America)
答案 1 :(得分:1)
您可以使用Jackson或SnakeYaml解析YAML文件。但是,Jackson不支持引用/锚,而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对象,该对象使我们能够转换为其他数据类型。