はじめに
YAML
またデータシリアライゼーション
本特集では、
YAMLライブラリの内部処理について
ここで、

- parse
- YAML文字列を構文解析し、
イベントの列に変換します。たとえば 「{10, 20}」 というYAML文字列は、 「StartSequence, ScalarData, ScalarData, EndSequence」 というイベントの列に変換されます。 - compose
- イベントの列をノードに変換します
[3]。ノードは3種類あり、 シーケンス、 マッピング、 スカラーを表します。 - construct
- ノードをデータに変換します。たとえばスカラーを表すノードは文字列や数値に変換されます。
- represent
- constructの逆で、
データをノードに変換します。 - serialize
- composeの逆で、
ノードをイベントの列に変換します。 - present(emit)
[4] - parseの逆で、
イベントの列を文字列に変換します。
またparse、
これらの詳細については、
イベントやノードについて調べる方法は、
ここで、 現在のところ、 これにはいくつかの原因があります。 このようにYAMLのライブラリは互換性が高くないので、 ただし、 もう一つ、 参考までに、# -*- coding: utf-8 -*-
## 使い方: python yaml-internal.py [file.yaml]
import sys
import yaml
## ファイルまたは標準入力からYAML文字列を読み込む
filename = len(sys.argv) > 1 and sys.argv[1] or None
input = (filename and open(filename) or sys.stdin).read()
input = input.encode('utf8') ## 文字コードを変換する
## YAML文字列をイベントの列に変換する
print "===== events ====="
for event in yaml.parse(input):
print event
## YAML文字列からノードを生成する
print "===== node graph ====="
node = yaml.compose(input)
print node
$ cat example.yaml
- abc
- 123
- {x: 10, y: 20}
$ python yaml-internal.py example.yaml
===== events =====
StreamStartEvent()
DocumentStartEvent()
SequenceStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'abc')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'123')
MappingStartEvent(anchor=None, tag=None, implicit=True)
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'x')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'10')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'y')
ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'20')
MappingEndEvent()
SequenceEndEvent()
DocumentEndEvent()
StreamEndEvent()
===== node graph =====
SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[
ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'abc'),
ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'123'),
MappingNode(tag=u'tag:yaml.org,2002:map', value=[
( ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'x'),
ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'10')
),
( ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'y'),
ScalarNode(tag=u'tag:yaml.org,2002:int', value=u'20')
)
])
])
YAMLライブラリの互換性について
など
タブ文字について
def untabify(str, width=8)
return '' if !str || str.empty?
list = str.split(/\t/)
last = list.pop
return last if list.empty?
sb = ''
list.each do |s|
column = (n = s.rindex(?\n)) ? s.length - n - 1 : s.length
n = width - (column % width)
sb << s << (' ' * n)
end
sb << last
return sb
end
function untabify($str, $width=8) {
if (! $str) return '';
$splitted = preg_split('/\t/', $str);
$last = array_pop($splitted);
if (! $splitted) return $last;
$buf = array();
foreach ($splitted as $s) {
$buf[] = $s;
if (($rindex = strrpos($s, "\n")) !== FALSE)
$column = strlen($s) - $rindex - 1;
else
$column = strlen($s);
$n = $width - ($column % $width);
$buf[] = str_repeat(' ', $n);
}
$buf[] = $last;
return join($buf);
}