XmlSimple (ruby) を使ってみる

PerlXML::Simple のruby port であるxml-simple(http://xml-simple.rubyforge.org/)を使ってみる.XMLを(連想)配列にマップしてくれます.

インストール

gem install xml-simple

使い方

require 'rubygems'
require 'xmlsimple'

xml = %q(
  <config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
    <server name="sahara" osname="solaris" osversion="2.6">
      <address>10.0.0.101</address>
      <address>10.0.1.101</address>
    </server>
    <server name="gobi" osname="irix" osversion="6.5">
      <address>10.0.0.102</address>
    </server>
    <server name="kalahari" osname="linux" osversion="2.0.34">
      <address>10.0.0.103</address>
      <address>10.0.1.103</address>
    </server>
  </config>
)
config = XmlSimple.xml_in(xml)

として,(require 'pp'の後)

pp config

をすると,次のように連想配列になっていることが分かります.

{"logdir"=>"/var/log/foo/",
 "server"=>
  [{"name"=>"sahara",
    "osversion"=>"2.6",
    "osname"=>"solaris",
    "address"=>["10.0.0.101", "10.0.1.101"]},
   {"name"=>"gobi",
    "osversion"=>"6.5",
    "osname"=>"irix",
    "address"=>["10.0.0.102"]},
   {"name"=>"kalahari",
    "osversion"=>"2.0.34",
    "osname"=>"linux",
    "address"=>["10.0.0.103", "10.0.1.103"]}],
 "debugfile"=>"/tmp/foo.debug"}

なので,次のように値が取り出せます.

irb(main):024:0> config["server"][0]["name"]
=> "sahara"
irb(main):025:0> config["server"][2]["name"]
=> "kalahari"
irb(main):026:0> config["server"][2]["address"]
=> ["10.0.0.103", "10.0.1.103"]

連想配列XMLにしたければ

XmlSimple.xml_out(config)

とします.また,XmlSimple.xml_in で読み込んだ内容はただの連想配列なので,YAMLに変換するには,to_yamlをしてあげればオッケー.

irb(main):030:0> puts config.to_yaml
--- 
logdir: /var/log/foo/
server: 
- name: sahara
  osversion: "2.6"
  osname: solaris
  address: 
  - 10.0.0.101
  - 10.0.1.101
- name: gobi
  osversion: "6.5"
  osname: irix
  address: 
  - 10.0.0.102
- name: kalahari
  osversion: 2.0.34
  osname: linux
  address: 
  - 10.0.0.103
  - 10.0.1.103
debugfile: /tmp/foo.debug

個人的には,XML連想配列に格納するのではなく,PHP5のsimplexml (http://www.onlamp.com/pub/a/php/2004/01/15/simplexml.html 参照)やXerialJ/XMLBean(http://www.xerial.org/javadoc/XerialJ/api/org/xerial/util/xml/bean/XMLBeanUtil.html)の様にオブジェクトにマップした方が,プログラムが組みやすいように思えます
( RailsのActiveRecordsもDBをオブジェクトにマップしていますが,あんな感じのmappingをXMLで出来ればと.クラスを予め用意するのが省略できれば,なお良し・・・).