LoginSignup
2

More than 3 years have passed since last update.

nimでYaml操作

Last updated at Posted at 2018-09-29

概要

NimのYAML処理をコツコツと
NimYAMLの低レベルメソッドを試します。
NimYAMLの現行バージョン0.10.3だと、nim-0.19.0ではコンパイルエラーとなります。

追記(2019/07/08)

  • NimYamlのバージョン0.11.0では0.19.0対応しているそうです。
  • 残念ながら0.20.0には未対応でいくつかコンパイルエラーが発生します。

0.19.0で動かす場合は、NimYAMLをForkしたブランチをクローンして、nimble installを実行してください

# for nim-0.19.0
git clone -b "for-0.19.0" https://github.com/6in/NimYAML.git
cd NimYAML
nimble install

以下は、yaml.domを利用して一からYamlを組み立てるサンプルとなります。

以下メモ

低レベルなYaml構築

import yaml,yaml/presenter,yaml/serialization
import json,strutils,os,streams

block:
  # ヘルパー関数群
  proc y(val:string) : YamlNode = newYamlNode(val)
  proc y(val:int) : YamlNode = newYamlNode($val,"int")
  proc y(key,val:string) : YamlNode = newYamlNode( [ (y(key),y(val)) ] )
  # key,valueのペアからYamlNodeを生成
  proc y( keyValues: openArray[(string,string)] ) : YamlNode = 
    var kvs: seq[(YamlNode,YamlNode)] = @[]
    for kv in keyValues:
      kvs.add ( y(kv[0]), y(kv[1]) )
    result = newYamlNode(kvs)    
  # YamlNodeの配列を構築
  proc y( values: openArray[YamlNode] ) : YamlNode = 
    var vals: seq[YamlNode] = @[]
    for val in values:
      vals.add val
    result = newYamlNode(vals)
  # ファイルを表示
  proc cat(file:string) =
    let f = open(file,FileMode.fmRead)
    defer: f.close
    echo f.readAll
  # Yamlをダンプ
  proc dump(yamlDoc:YamlDocument ,file:string, style:PresentationStyle) =
    var s = newFileStream(file, fmWrite)
    yamlDoc.dumpDom(s, options= defineOptions(style = style) )
    s.close()
    cat(file)
  #
  # YamlDocを作成
  let yamlDoc = initYamlDoc( y([("string","val1")]) )
  #
  # 属性追加
  yamlDoc.root[y"number"] = y(2)
  # オブジェクトを追加
  yamlDoc.root[y"object"] = y("child1","3")
  # 配列を追加
  yamlDoc.root[y"array"] = y( [ y"child2", y"child3", y"child4", y"child5" ] )
  # 配列[オブジェクト]を追加
  yamlDoc.root[y"arrayObject"] = y( [ y("key1","val1"),y("key2","val2"),y("key3","val3") ] )
  #
  # Yamlをダンプ
  # psMinimal, psCanonical, psDefault, psJson, psBlockOnly
  echo "============================="
  echo "Yamlを表示(psMinimal)"
  yamlDoc.dump( "psMinimal.yaml", psMinimal)
  echo "============================="
  echo "Yamlを表示(psCanonical)"
  yamlDoc.dump( "psCanonical.yaml", psCanonical)
  echo "============================="
  echo "Yamlを表示(psDefault)"
  yamlDoc.dump( "psDefault.yaml", psDefault)
  echo "============================="
  echo "Yamlを表示(psJson)"
  yamlDoc.dump( "psJson.yaml", psJson)
  echo "============================="
  echo "Yamlを表示(psBlockOnly)"
  yamlDoc.dump( "psBlockOnly.yaml", psBlockOnly)
(stdout)
=============================
Yamlを表示(psMinimal)
%YAML 1.2
--- 
{string: val1, number: !<int> 2, object: {child1: 3}, array: [child2, child3, child4, child5], arrayObject: [{key1: val1}, {key2: val2}, {key3: val3}]}
=============================
Yamlを表示(psCanonical)
%YAML 1.2
--- 
{
  ? "string"
  : "val1",
  ? "number"
  : !<int> "2",
  ? "object"
  : {
    ? "child1"
    : "3"
  },
  ? "array"
  : [
    "child2",
    "child3",
    "child4",
    "child5"
  ],
  ? "arrayObject"
  : [
    {
      ? "key1"
      : "val1"
    },
    {
      ? "key2"
      : "val2"
    },
    {
      ? "key3"
      : "val3"
    }
  ]
}
=============================
Yamlを表示(psDefault)
%YAML 1.2
--- 
string: val1
number: !<int> 2
object: 
  child1: 3
array: [child2, child3, child4, child5]
arrayObject: 
  - 
    key1: val1
  - 
    key2: val2
  - 
    key3: val3
=============================
Yamlを表示(psJson)

{
  "string": "val1",
  "number": "2",
  "object": {
    "child1": 3
  },
  "array": [
    "child2",
    "child3",
    "child4",
    "child5"
  ],
  "arrayObject": [
    {
      "key1": "val1"
    },
    {
      "key2": "val2"
    },
    {
      "key3": "val3"
    }
  ]
}
=============================
Yamlを表示(psBlockOnly)
%YAML 1.2
--- 
string: val1
number: !<int> 2
object: 
  child1: 3
array: 
  - child2
  - child3
  - child4
  - child5
arrayObject: 
  - 
    key1: val1
  - 
    key2: val2
  - 
    key3: val3

文字列から構築

import yaml,yaml/presenter,yaml/serialization
import json,strutils,os,streams

block:
  # yamlDoc.root.new()
  let yamlDoc2 = loadDom("""
test:
  test1: 1
  """)
  echo $yamlDoc2
(stdout)
(root: !<?> {!<?> "test": !<?> {!<?> "test1": !<?> "1"}})

ファイルから構築

import yaml,yaml/presenter,yaml/serialization
import json,strutils,os,streams

block:
  let fileStream = newFileStream("psBlockOnly.yaml",FileMode.fmRead)
  let yamlDoc = loadDom( fileStream )
  defer:
    fileStream.close
  echo $yamlDoc
(stdout)
(root: !<?> {!<?> "string": !<?> "val1", !<?> "number": !<int> "2", !<?> "object": !<?> {!<?> "child1": !<?> "3"}, !<?> "array": !<?> [!<?> "child2", !<?> "child3", !<?> "child4", !<?> "child5"], !<?> "arrayObject": !<?> [!<?> {!<?> "key1": !<?> "val1"}, !<?> {!<?> "key2": !<?> "val2"}, !<?> {!<?> "key3": !<?> "val3"}]})

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2