I am trying to read YAML
file from Scala
and I am able to read the file using the code given below. One of the disadvantage I see here is the necessity for me to create case class
to have a mapping with the YAML
file I am using. Every time I change the content of YAML
it becomes necessary for me to change the case class
. Is there any way in Scala to read YAML
with out the need for me to create the case class
. (I have also used Python
to read YAML
; where we do not have the constraint of mapping a Class
with the YAML
structure...and would like to do similar thing in Scala
)
Note : When I add a new property in YAML
and if my case class
do not have a matching property I get 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
(This works with code)
country: US
state:
- TX
- VA
sample.yaml
(This throws Exception)
country: US
state:
- TX
- VA
continent: North America
You could parse the Yaml file and load it as a collections object instead of case case. But this comes at the cost of losing typesafety in your code. The Below code uses the load
function supported by Yaml
. Note that the load
has overloaded methods to read from a inputstream/reader as well..
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
Now data is a scala mutable collection instead of a case class
data: scala.collection.mutable.Map[String,Any] = Map(country -> US, state -> [TX, VA], continent -> North America)