【问题标题】:Scala: Parse a Yaml file using SnakeYamlScala:使用 SnakeYaml 解析 Yaml 文件
【发布时间】:2015-08-31 07:13:47
【问题描述】:

我对 scala 很陌生。我试图在scala中使用snakeyaml解析一个Yaml文件。我正在获取数据,但它是对象的形式。我可以将对象转换为字符串,但它违背了使用 Yaml 的全部目的。

例如我正在使用的文件是带有数据的“abcd.yaml”

aa:
  - x
  - y
bb: z

我的代码是这样的:

import java.io.{File, FileInputStream}
import org.yaml.snakeyaml.Yaml

def parseYaml(){
val ios = new FileInputStream(new File("abcd.yaml"))
val yaml = new Yaml()
val obj = yaml.load(ios)
}

但是在这里我得到一个对象,我不能使用里面的值。 有什么解决办法吗?

【问题讨论】:

  • 根据文档,您必须强制转换才能从返回的文档中获取任何有意义的内容。尝试将其转换为 Map[String,Any] 看看是否可行
  • 嗨,我试过了,但我总是收到这样的错误(我使用 asInstanceOf[Map[String, Any]):线程“main”中的异常 java.lang.ClassCastException:java.lang.ClassCastException util.LinkedHashMap 不能转换为 scala.collection.immutable.Map

标签: scala parsing yaml snakeyaml


【解决方案1】:

我得到了解决方案,它是转换为 java maps 而不是 scala maps:

只需使用asInstanceOf[java.util.Map[String, Any],它就像一个魅力。 解决办法是这样调用load:

    val obj = yaml.load(ios).asInstanceOf[java.util.Map[String, Any]]

【讨论】:

    【解决方案2】:

    为了解压单个级别的 YAML 文件,例如

    aa:
     - x
     - y
    bb: z
    

    解决方案是将其转换为您在解压缩 YAML 文件后希望收到的数据类型,即 Map[, ],通常最优选的是 Map[String, Any] 以适应检索到的任何数据类型.

    val obj = yaml.load(ios).asInstanceOf[java.util.Map[String, Any]]
    

    这是最简单的解决方案,但是,当您在 YAML 文件中有多个级别时,此方法会变得难以使用,那么您将不得不将新对象转换为 Map/List,每次您更深一层。例如 YAML 文件:

    aa:
     - x
     - y
    bb: z
    cc:
      p: abc
      q: 123
      r: true
      s:
        - listItem1
        - listItem2
        - listItem3
    

    在这种情况下,依靠 SnakeYAML 解析文件并依靠 Jackson YAML 遍历文件是最好的,因为我们在 Jackson 的 JsonNode 数据类型中具有灵活性

    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 have Anchors and reference support
    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 可以使用 JsonNode 的 at 或 get 方法解析:

    jsonObj.at("/cc/r").asBoolean // Returns boolean of value in r
    jsonObj.get("bb") // Returns the value in key bb
    

    利用JsonNode 中的asText、asBoolean、asInt 等方法将简化数据提取和类型转换过程

    【讨论】:

      猜你喜欢
      • 2020-03-12
      • 2014-04-11
      • 2016-05-15
      • 2020-10-14
      • 2020-07-18
      • 1970-01-01
      • 2014-09-16
      • 2013-02-08
      • 1970-01-01
      相关资源
      最近更新 更多