JavaのYAMLライブラリって

YAMLって記述性が高いのでわりと好きです。ただ、言語によってYAMLプロセッサーの品質がまちまちなので困ってしまうことがあります。Perlは複数の実装があるけどYAML::Syckで全然問題なく使えるから良いんですが、Javaに関してはいけてないYAMLプロセッサーがあったり(でも割と有名なライブラリ?)して大変です。

JavaによるYAMLプロセッサーと言えば(2008/01/17時点で)主に

  • JYaml
  • JvYAML

の二つあると思います。これぐらいしか知りません見つかりません。他にあったら是非教えて下さい。

で、「この二つのうちどちらを選ぶ?」という話であればJvYAMLと答えます。JvYAMLはちゃんと使えます。

でも、ここではJYamlのいけてなさ加減をちょっと書いてみようと思います。 JYamlは正しいYAML定義であっても例外を吐いて死んでしまうことがあります。以下のようなフロースタイルで記述されたYAMLドキュメントがあった場合

{ name: keiji, age: 23 }

JYamlは正しくパースしてくれず、変わりに以下のような例外を吐いて死にます(因みにJvYAMLは正しくパースしてくれます)。

org.ho.yaml.exception.YamlException: Error near line 1: End of document expected.
    at org.ho.yaml.JYamlParserEvent.error(Unknown Source)
    at org.ho.yaml.YamlDecoder.firstDocument(Unknown Source)
    at org.ho.yaml.YamlDecoder.readObject(Unknown Source)
    at org.ho.yaml.YamlConfig.load(Unknown Source)
    at org.ho.yaml.YamlConfig.load(Unknown Source)
    at org.ho.yaml.YamlConfig.load(Unknown Source)
    at org.ho.yaml.Yaml.load(Unknown Source)

ただ、JYamlはフロースタイルが全く処理できない訳ではなく

--- { name: keiji, age: 23 }

というようにYAMLドキュメントの開始を示す文字列「---」を付けてあげるときちんとパースしてくれるようになります。ちょっと(というかかなり)アレですけどラッパーを作ることで回避できるので目をつむることにします。

でも処理できないのは上記のようなケースだけではなく、以下のように

--- {
  name: keiji,
  age: 23
}

フロースタイル中に改行(多分改行が原因だと思われ、推測で言ってる)があるようなYAMLドキュメントを書くとドキュメントのパース中に謎のNullPointerExceptionが発生したりします。まぁこいつの回避策としては、これまたラッパーで改行を消しちゃうという荒技を使えば一応回避できるんですが「なんていけてないYAMLパーサなんだ」と思ってしまいます(因みにJvYAMLは正しくパースしてくれます)。

まぁフロースタイルだけが駄目という訳ではなく、ブロックスタイルでも例外吐いて死んだりすることがあります。いけてないJYamlにフロースタイルとブロックスタイルを混合したようなYAMLドキュメントを処理させると、どんな死に方をするかは詳しく調べてないんですがスタイルを混合して書くようなドキュメントをパースさせるのはやめておいた方が無難です。無用にはまります。これってかなり致命的な気がする。

フロースタイルだけなら「JSON使えば?」って感じですけどね。JSON-libあるし、

{
  "name" : "keiji"
  "age": 23
}

ただ、ダブルクォーテーションで囲みたくないっていう気持ちはあります。Perlでハッシュコンストラクタと=>演算子を使うと

{
  name => 'keiji',
  age  => 23,
}

て書けてクォーテーションが無い方がやっぱり見栄えが良いじゃないですか。Rubyだとシンボルで定義するのかな?

{
  :name => 'keiji',
  :age  => 23
}

なんかどんどん横道にそれていってますけどJvYAMLを使えば別に問題はないです。JYamlなんて使わなくてもJvYAML使っとけばいいんです。

Map map = (Map) YAML.load("{名前: 恵示, 年齢: 23}");
assertEquals("恵示", map.get("名前"));

でもね。残念なことにjvyamlってmavenリポジトリに登録されてないんですよね。自分でどこかのリポジトリにデプロイしないといけないのでそこがちょっとね。

0 コメント:

Twitter Updates

About Me

My photo
1984/07/05生 プログラマー

サイト内検索