概要
Ruby の xmlsimple ライブラリを使ってハッシュから XML を生成してみました
基本的な使い方から使う際のポイントを紹介します
環境
- macOS 10.13.4
- Ruby 2.5.1p57
- xmlsimple 1.1.5
xml_out のサンプル
とりあえずサンプルです
今回は AWS の route53 でゾーンを作成するために必要な XML CreateHostedZoneRequest を作成してみます
ハッシュを定義してそれを食わすことで XML を出力しています
require 'xmlsimple'
body = {
'@xmlns' => 'https://route53.amazonaws.com/doc/2013-04-01/',
'Name' => ['content' => ''],
'CallerReference' => ['content' => ''],
'HostedZoneConfig' => {
'Common' => ['content' => ''],
'PrivateZone' => ['content' => ''],
},
'DelegationSetId' => ['content' => ''],
'VPC' => {
'VPCId' => ['content' => ''],
'VPCRegion' => ['content' => ''],
}
}
options = {
'AttrPrefix' => true,
'RootName' => 'CreateHostedZoneRequest',
'ContentKey' => 'content'
}
puts XmlSimple.xml_out(body, options)
結果は以下のようになります
どうしてこうなるのか詳細を説明します
<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
<Name></Name>
<CallerReference></CallerReference>
<HostedZoneConfig>
<Common></Common>
<PrivateZone></PrivateZone>
</HostedZoneConfig>
<DelegationSetId></DelegationSetId>
<VPC>
<VPCId></VPCId>
<VPCRegion></VPCRegion>
</VPC>
</CreateHostedZoneRequest>
説明
XML に変換する対象のハッシュ body
はとりあえずおいておきます
XmlSimple では hash -> XML の変換ルールを options
で定義します
今回は AttrPrefix, RootName, ContentKey の 3 つの設定をしています
他にも様々な設定ルールがあります
(サイトは CPAN のドキュメントになります)
その中でも上記 3 つのオプションはよく使うと思います
それぞれ説明すると
- AttrPrefix・・・
@
で始まるキーがあった場合はそれを XML のタグとして使用せず属性として使用する - RootName・・・XML のルートドキュメントの名前を指定します、これを指定しない場合は
<opt>
になってしまいます - ContentKey・・・XML の値として使用するデータを明示的に指定することができます
となります
ここで body
とそれぞれのオプションの効果を見ていきます
まず冒頭の '@xmlns' => 'https://route53.amazonaws.com/doc/2013-04-01/'
ですがこれは AttrPrefix
の効果でタグにはなりません
ルートの位置で定義しているのでルートの属性情報として使用されます
<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
次にハッシュの各所に定義してある ['content' => '']
ですが、これは ContentKey
が影響します
このオプションの値とハッシュ内で使われている値がどちらも content
になっているのがわかると思います
つまりこの content の値で指定したデータが XML に出力されたときのタグないのデータになるわけです
ContentKey
は必須ではないですが、タグに属性が入る場合はほぼ必須になると思います
またデータとなるキーがわかりやすくもなるので使うことをおすすめします
最後に RootName
ですがこれは生成したい XML ルートを指定するだけです
Tips
XML declaration を定義したい
例えば <?xml version='1.0' standalone='yes'?>
の情報です
XML の先頭に付与する情報になります
XmlDeclaration
というオプションが使えるのでそれを使います
先頭に追加したい文字列を直接指定することで追加することができます
options = {
'AttrPrefix' => true,
'RootName' => 'CreateHostedZoneRequest',
'ContentKey' => 'content',
'XmlDeclaration' => '<?xml version=\'1.0\' standalone=\'yes\'?>'
}
xml_in は可逆ではない
例えば今回生成できた XML をそのまま xml_in
メソッドに投げも同じハッシュを得ることはできません
out = XmlSimple.xml_out(body, options)
pp XmlSimple.xml_in(out)
{"xmlns"=>"https://route53.amazonaws.com/doc/2013-04-01/",
"Name"=>[{}],
"CallerReference"=>[{}],
"HostedZoneConfig"=>[{"Common"=>[{}], "PrivateZone"=>[{}]}],
"DelegationSetId"=>[{}],
"VPC"=>[{"VPCId"=>[{}], "VPCRegion"=>[{}]}]}
当然と言えば当然ですが上記のようになります
ハッシュからデータを取得するときに気をつけるのはデータの部分が必ず配列に格納されている点ですデータが 1 つしかなくても配列に入ります
最後に
Ruby の xmlsimple を使ってハッシュから XML を生成してみました
結構クセのある使い方をするのとドキュメントが少ないのが辛い点です
ハッシュから XML に変換するのであればこの方法でも良いですが単純に XML を欲しいだけであれば nokogiri や rexml でも生成できます
もしくは erb を使って XML をテンプレート化すればそこからでも XML 情報を生成することができます
今回紹介した方法も XML を生成する手段の一つにしかすぎませんので各自の環境にあった最適な方法を選択するようにしてください
0 件のコメント:
コメントを投稿