我正在使用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
执行此操作的方法。我错过了什么吗?
答案 0 :(得分:6)
我发现XML::Simple
不直观且使用起来很尴尬。很容易最终只是抛出随机选项来试图让它发挥作用。
但是如果你坚持下去就有办法。首先,ForceArray
选项非常有用,正如文档所述,
查看“ForceArray”,因为你几乎肯定想打开它
因此,您需要调整数据,以便在解析原始XML时看起来ForceArray
生效。这只涉及将所有数据放入一个匿名数组,这些数据应该是元素的内容而不是属性值。
此代码可满足您的需求。 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
元素,使用{将所有name
和capacity
个子节点设置为元素{1}}。
请注意,XML是使用set_tag
输出的,因为在列表上下文中调用时
scalar $smart->data()
方法将返回第二个值:一个布尔标志,指示XML是否是Unicode编码的。这似乎没有记录在POD中。
如果您对XML中属性和元素的显示顺序不感兴趣,则可以省略对data
的调用。
$smart->set_order
<强>输出强>
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);
答案 1 :(得分: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>
答案 2 :(得分:0)
Daxim的回答已经是正确的。因为我输入了它,所以我会发布这个。这是一段代码,可以将您的数据结构转换为您需要的数据结构(Daxim已经指出过)。
my $stuff = {
'room' => [
map { {
'id' => $_->{'id'},
'is_key' => $_->{'is_key'},
'name' => [ $_->{'name'} ],
'capacity' => [ $_->{'capacity'} ]
} } @rooms
]
};
print XMLout($stuff, RootName=> 'rooms', );