4

私は使用してXML::Simpleおり、このデータを XML に変換したいと考えています。

@rooms = (
   {
      id => 4,
      is_key => 0,
      name => B507,
      capacity => 35
   },
   {
      id => 5,
      is_key => 1,
      name => B502,
      capacity => 24
   }
);

これを出力したい:

<rooms>
   <room id=4 is_key=0>
      <name>B507</name>
      <capacity>35</capacity>
   </room>
   <room id=5 is_key=1>
      <name>B502</name>
      <capacity>24</capacity>
   </room>
</rooms>

でこれを行う方法がわかりませんXML::Simple::XMLout。何か不足していますか?

4

3 に答える 3

6

私はXML::Simple直感的でなく、使用するのが非常に厄介だと思います。それを機能させるためにランダムなオプションを投げるだけで終わるのは簡単です。

しかし、あなたがそれに固執しているなら、方法があります。まず第一に、このForceArrayオプションは非常に便利であり、ドキュメントにあるように、

ほぼ確実にオンにしたいので、「ForceArray」をチェックしてください

ForceArrayしたがって、元のXMLが解析されたときに有効であるように見えるようにデータを調整する必要があります。これには、属性値ではなく要素のコンテンツである必要があるすべてのデータを匿名配列に入れるだけです。

このコードはあなたが必要とすることをします。このKeepRootオプションはXMLout、最上位のハッシュがルート要素であり、すべてを別の要素でラップする必要がないことを示しているだけです。

use strict;
use warnings;

use XML::Simple;

my @rooms = (
   {
      id => 4,
      is_key => 0,
      name => 'B507',
      capacity => 35
   },
   {
      id => 5,
      is_key => 1,
      name => 'B502',
      capacity => 24
   }
);

for my $room (@rooms) {
  for my $k (keys %$room) {
      $room->{$k} = [ $room->{$k} ] unless grep $k eq $_, qw/ is_key id /;
  }
}

my $xml = {rooms => {room => \@rooms} };

print XMLout($xml, KeepRoot => 1);

出力

<rooms>
  <room id="4" is_key="0">
    <name>B507</name>
    <capacity>35</capacity>
  </room>
  <room id="5" is_key="1">
    <name>B502</name>
    <capacity>24</capacity>
  </room>
</rooms>

アップデート

を使用したソリューションをXML::Smartお勧めします。これにより、どのノードが要素で、どのノードがタグであるかを指定できます。これにより、元のデータを@roomsそのままにしておくことができます。

このプログラムは、ソリューションへの同様のハッシュ参照を受け入れ、すべての要素XML::Simpleをループして、を使用してすべてのノードと子ノードを要素/rooms/roomに設定します。namecapacityset_tag

scalar $smart->data()リストコンテキストで呼び出されると、dataメソッドは2番目の値(XMLがUnicodeでエンコードされているかどうかを示すブールフラグ)を返すため、XMLはを使用して出力されることに注意してください。これはPODに文書化されていないようです。

$smart->set_order属性と要素がXMLに表示される順序が気にならない場合は、への呼び出しを省略できます。

use strict;
use warnings;

use XML::Smart;

my @rooms = (
   {
      id => 4,
      is_key => 0,
      name => 'B507',
      capacity => 35
   },
   {
      id => 5,
      is_key => 1,
      name => 'B502',
      capacity => 24
   }
);

my $smart = XML::Smart->new;
$smart->{rooms} = { room => \@rooms };

for my $room (@{$smart->{rooms}{room}}) {
  $room->set_order(qw/ id is_key name capacity /);
  $room->{name}->set_tag;
  $room->{capacity}->set_tag;
}

print scalar $smart->data(noheader => 1, nometagen => 1);

出力

<rooms>
  <room id="4" is_key="0">
    <name>B507</name>
    <capacity>35</capacity>
  </room>
  <room id="5" is_key="1">
    <name>B502</name>
    <capacity>24</capacity>
  </room>
</rooms>
于 2012-07-20T16:00:46.093 に答える
2

ハッシュ値 arrayrefs は XML 要素コンテンツになり、単純なハッシュ値は XML 属性値になります。

use strictures;
use XML::Simple qw(:strict);

print XMLout(
    {
        room => [
            {
                id       => 4,
                is_key   => 0,
                name     => ['B507'],
                capacity => [35],
            },
            {
                id       => 5,
                is_key   => 1,
                name     => ['B502'],
                capacity => [24],
            }
        ]
    },
    KeyAttr  => [],
    RootName => 'rooms'
);

<rooms>
  <room id="4" is_key="0">
    <capacity>35</capacity>
    <name>B507</name>
  </room>
  <room id="5" is_key="1">
    <capacity>24</capacity>
    <name>B502</name>
  </room>
</rooms>
于 2012-07-20T15:53:09.753 に答える
0

Daximの答えはすでに正しいです。入力したので、とにかく投稿します。これは、データ構造を必要なものに変換するコードです(Daximはすでに指摘しています)。

my $stuff = { 
  'room' =>  [ 
    map { { 
      'id' => $_->{'id'}, 
      'is_key' => $_->{'is_key'}, 
      'name' => [ $_->{'name'} ], 
      'capacity' => [  $_->{'capacity'} ] 
    } } @rooms 
  ]
};

print XMLout($stuff, RootName=> 'rooms', );
于 2012-07-20T16:01:18.610 に答える