2013-10-18 9 views

答えて

21

SnakeYAMLは、Java用に高品質かつ積極的に管理されているYAMLパーサ/レンダラです。もちろんScalaから使用することができます。

HelicalYAMLは、実際にその利便性を望む場合、SnakeYAML用のScalaラッパーを提供しますが、プロジェクトの品質や長寿命を証明することはできません。

一般的なASTにJSONまたはYAML(または何でも差し替え可能)のいずれかを解析し、型付けを使用してScalaオブジェクトを構築できるライブラリが大好きです。いくつかのJSONライブラリーは同じように動作します(もちろん、同じタイプキャストを使用してオブジェクト用のJSONをレンダリングすることもできます)。しかし、YAML用のこのような機能についてはわかりません。

+0

HelicalYAMLは現時点では維持されていません(プロジェクトのウェブサイトによると、最新のコミットは2010年です) – fikovnik

+2

私にとってSnakeYAMLを使用する主な欠点は、自動解析を必要とするならば、反射を使ってそれで私は2つのクラスを書くことができます。 @BeanPropertiesを持つコードとBeany-Oneで使用する不変のものと、不変のコンパニオンを構築するためにその上に構築メソッドを持つJavaコレクションを使用するもの。私は何か見落としてますか?たぶん、ダブルコーディングから私を解放するいくつかのマクロベースのメタプログラミングソリューションがありますか? –

4

この回答を実行し、ヘルプとサンプルを探している人は、basic exampleが見つかりました。それはsnakeYAMLを使用しています。コードは次のとおりです。

package yaml 

import org.yaml.snakeyaml.Yaml 
import org.yaml.snakeyaml.constructor.Constructor 
import scala.collection.mutable.ListBuffer 
import scala.reflect.BeanProperty 

object YamlBeanTest1 { 

    val text = """ 
    accountName: Ymail Account 
    username: USERNAME 
    password: PASSWORD 
    mailbox: INBOX 
    imapServerUrl: imap.mail.yahoo.com 
    protocol: imaps 
    minutesBetweenChecks: 1 
    usersOfInterest: [barney, betty, wilma] 
    """ 

    def main(args: Array[String]) { 
    val yaml = new Yaml(new Constructor(classOf[EmailAccount])) 
    val e = yaml.load(text).asInstanceOf[EmailAccount] 
    println(e) 
    } 

} 

/** 
* With the Snakeyaml Constructor approach shown in the main method, 
* this class must have a no-args constructor. 
*/ 
class EmailAccount { 
    @BeanProperty var accountName: String = null 
    @BeanProperty var username: String = null 
    @BeanProperty var password: String = null 
    @BeanProperty var mailbox: String = null 
    @BeanProperty var imapServerUrl: String = null 
    @BeanProperty var minutesBetweenChecks: Int = 0 
    @BeanProperty var protocol: String = null 
    @BeanProperty var usersOfInterest = new java.util.ArrayList[String]() 

    override def toString: String = { 
    return format("acct (%s), user (%s), url (%s)", accountName, username, imapServerUrl) 
    } 
} 
20

ここでは、Jackson YAMLデータバインディングの使用例を示します。

name: test 
parameters: 
    "VERSION": 0.0.1-SNAPSHOT 

things: 
    - colour: green 
    priority: 128 
    - colour: red 
    priority: 64 

は、これらの依存関係の追加:

まず、ここで私たちのサンプル文書です

libraryDependencies ++= Seq(
    "com.fasterxml.jackson.core" % "jackson-core" % "2.1.1", 
    "com.fasterxml.jackson.core" % "jackson-annotations" % "2.1.1", 
    "com.fasterxml.jackson.core" % "jackson-databind" % "2.1.1", 
    "com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % "2.1.1" 
) 

ここに私たちの最も外側のクラスがありますが(前提条件は、グアバのようなチェックですと言っフィールドがない場合は、例外を発生させますYAML内):

import java.util.{List => JList, Map => JMap} 
import collection.JavaConversions._ 
import com.fasterxml.jackson.annotation.JsonProperty 

class Sample(@JsonProperty("name") _name: String, 
      @JsonProperty("parameters") _parameters: JMap[String, String], 
      @JsonProperty("things") _things: JList[Thing]) { 
    val name = Preconditions.checkNotNull(_name, "name cannot be null") 
    val parameters: Map[String, String] = Preconditions.checkNotNull(_parameters, "parameters cannot be null").toMap 
    val things: List[Thing] = Preconditions.checkNotNull(_things, "things cannot be null").toList 
} 

ここに内部オブジェクトがあります。

import com.fasterxml.jackson.annotation.JsonProperty 

class Thing(@JsonProperty("colour") _colour: String, 
      @JsonProperty("priority") _priority: Int { 
    val colour = Preconditions.checkNotNull(_colour, "colour cannot be null") 
    val priority = Preconditions.checkNotNull(_priority, "priority cannot be null") 
} 

は最後に、ここでそれをインスタンス化する方法は次のとおりです。

val reader = new FileReader("sample.yaml") 
val mapper = new ObjectMapper(new YAMLFactory()) 
val config: Sample = mapper.readValue(reader, classOf[Sample]) 
+0

ジャクソンライブラリーのイントレスト使用。 –

+0

私は今何ヶ月もアプリケーション設定を維持するために 'jackson-dataformat-yaml'を使ってきました。 SnakeYamlよりも優れています。 –

+0

例をありがとうございます!私はGuavaの前提条件を次のように変更します: 'require(_colour!= null、" colorはnullにできません "); val color = _colour' – r90t

2

だから私はコメントするのに十分な評判(41気圧)を持っていませんが、私は私の経験は、言及する価値だと思いました。

このスレッドを読んだ後、私は引数のないコンストラクタを必要としなかったので、Jackson YAMLパーサーを使用することにしました。私が気づいていなかったのは、は継承(マージ)のサポートがなく、アンカー参照のサポートが限られています(YAMLの全体の点ではないのですか?)。

マージはhereと説明されています。

アンカーリファレンスはhereと説明されています。複雑なアンカーリファレンスがサポートされているように見えますが、単純なケースでは動作できませんでした。

16

パーティーに少し遅れましたが、この方法は最もシームレスに機能すると思います。この方法ではあります

  1. BeanProperty/JsonPropertyのようなScalaのコレクション型への自動変換
  2. ユースケースクラス
  3. 定型的なコードは必要ないが
  4. Jackson-YAML & Jackson-scala

コードを使用します

import com.fasterxml.jackson.databind.ObjectMapper 
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory 
import com.fasterxml.jackson.module.scala.DefaultScalaModule 

case class Prop(url: List[String]) 

// uses Jackson YAML to parsing, relies on SnakeYAML for low level handling 
val mapper: ObjectMapper = new ObjectMapper(new YAMLFactory()) 

// provides all of the Scala goodiness 
mapper.registerModule(DefaultScalaModule) 
val prop: Prop = mapper.readValue("url: [abc, def]", classOf[Prop]) 

// prints List(abc, def) 
println(prop.url) 
+1

3年後は少し遅れますか? –

+3

Scalaはタイムレスです! :-) –

+2

3年* *遅い*この*トピック - それはまだ完全に解決されたものではありません与えられます。上記のライブラリをうまく使っていますが、引き続き特定の問題を抱えています。 – javadba

1

私の経験では、Scala用のJSONライブラリは成熟して使いやすくなっています(YAMLのアプローチのどれも、ケースクラスの扱いやカスタムのシリアライザとデシリアライザの作成に関して、JSONの同等のものほど魅力的ではありません)。

私はYAMLからJSONに変換し、JSONライブラリを使用する方が好きです。これは少しクレイジーに聞こえるかもしれないが、それは本当によくあること提供作品:

  • あなただけの性能JSONのサブセット(私の経験では、ユースケースの多大)
  • パスではありませんYAMLを使用して作業しています

私はYAMLからJSONに変換するために使用したアプローチが活用ジャクソン(このアプローチを取っにおけるオーバーヘッドがあるとして)重要:

val tree = new ObjectMapper(new YAMLFactory()).readTree(yamlTemplate) 

val json = new ObjectMapper() 
     .writer(new DefaultPrettyPrinter().withoutSpacesInObjectEntries()) 
     .writeValueAsString(tree) 
+1

moultingyamlについてどう思いますか?私の答えは – akauppi

4

私は0に出くわしました今日はです。

MoultingYAMLは、spray-jsonに基づくSnakeYAML用のScalaラッパーです。

spray-jsonで長年働いていたことは私にはよく似ています。私はそれが@ sihilの「魅力的」な「成熟した」Scala YAMLライブラリの必要性に合うかもしれないと思う。

+0

です。Moultingyamlは、非常に限定された範囲である単一のケースをサポートしているようです。ネストマップとリストのサポートが必要です。 – javadba

+0

Moultingyamlはspray.jsonと同じ抽象化レベルをとり、spray.jsonでは約20行のパターンマッチを行い、あなたが望むと思うものを処理できます。 – akauppi

関連する問題