2017-02-22 2 views
0

Je suis en train de lire le fichier YAML de Scala et je suis capable de lire le fichier en utilisant le code ci-dessous. Un des inconvénients que je vois ici est la nécessité pour moi de créer case class pour avoir un mapping avec le fichier YAML que j'utilise. Chaque fois que je change le contenu de YAML il devient nécessaire pour moi de changer le case class. Est-il possible dans Scala de lire YAMLsans sortir la nécessité pour moi de créer le case class. (Je l'ai aussi utilisé Python lire YAML, où nous n'avons pas la contrainte de cartographier une Class avec la structure YAML ... et je voudrais faire des choses similaires dans Scala)Lecture YAML dans Scala sans «classe de cas»

Remarque: Lorsque j'ajoute un nouvelle propriété dans YAML et si mon case class ne pas une propriété correspondant je reçois 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 (Cela fonctionne avec le code)

country: US 
state: 
    - TX 
    - VA 

sample.yaml (Ce throws Exception)

country: US 
state: 
    - TX 
    - VA 
continent: North America 

Répondre

2

Vous pouvez analyser le fichier YAML et le charger en tant que collections objet au lieu de cas le cas. Mais cela vient au prix de perdre la sécurité des types dans votre code. Le code ci-dessous utilise la fonction load prise en charge par Yaml. Notez que le load a overloaded methods à lire d'un flux entrant/lecteur et ..

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 

Maintenant données est une collection scala mutable au lieu d'une classe de cas

data: scala.collection.mutable.Map[String,Any] = Map(country -> US, state -> [TX, VA], continent -> North America)