XML::Simple#XMLoutで元のXMLに戻らない問題→解決

エントリーを書いてる途中に解決しましたがメモっておきます。

use XML::Simple;
use Data::Dumper;
my $xml = <<'XML';
<a>
 <b>
  <c>
   <d>
   </d>
  </c>
 </b>
</a>
XML

$\ = "\n";
print $xml;
my $obj = XMLin($xml);   # XMLを入力して
print Dumper($obj);      # 中身を確認し、
print XMLout( $obj, NoAttr => 1, RootName => 'a' ); # XMLとして出力してみる

を実行してみると、

<a>
 <b>
  <c>
   <d>
   </d>
  </c>
 </b>
</a>

$VAR1 = {
          'b' => {
                 'c' => {
                        'd' => {}
                      }
               }
        };

<a>
  <b>
    <name>c</name>
    <d></d>
  </b>
</a>

となり、となって欲しいところが、cとなってしまう。で、あれこれ悩んでいたんだけども、オブジェクトの段階で、(ルート以外の)単独のハッシュリファレンスが配列リファレンスで包まれているようにすればいいみたい。(XMLinの場合はmy $obj = XMLin($xml, ForceArray=>1)とする。)

思った通りの(常識的な)動きにしたい場合は、

  • XMLinにはForceArray=>1を付ける
  • オブジェクト内に単独のハッシュリファレンスが現れないようにする(上記を行なった場合はそうなっている)
  • XMLoutにはNoAttr=>1とRootName=>'ルート名'を付ける。(そうしなければanon要素やらopt要素やらが出現する場合がある)

を心がければ良さそう。

思いっきりFAQに載ってましたorz XML::Simple::FAQ - Frequently Asked Questions about XML::Simple - metacpan.org XMLoutのオプションでKeyAttr=>[]とするだけで良かったです。恥さらしエントリとして残しておきます。