我正在使用XML :: Simple来解析XML文件。代码在下面给出了XML文件,
use Tie::IxHash;
tie %$data, "Tie::IxHash";
use XML::Simple;
use Data::Dumper;
$xml = new XML::Simple;
$data = $xml->XMLin("ship_order.xml");
print Dumper($data);
XML文件,(ship_order.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<shipment>
<shiptoaddress>
<name>Prasad</name>
<address>AnnaNagar</address>
</shiptoaddress>
<items>
<quantity>5</quantity>
<price>100</price>
</items>
<items>
<quantity>6</quantity>
<price>50</price>
</items>
<num_of_items>2</num_of_items>
</shipment>
即使我使用Tie :: IxHash模块,输出也没有按顺序排列。
我的输出:
$VAR1 = {
'num_of_items' => '2',
'shiptoaddress' => {
'name' => 'Prasad',
'address' => 'AnnaNagar'
},
'items' => [
{
'quantity' => '5',
'price' => '100'
},
{
'quantity' => '6',
'price' => '50'
}
]
};
答案 0 :(得分:6)
啊,但你没有使用Tie::IxHash
。或者更确切地说,您开始使用Tie::IxHash
然后销毁它:
$data = $xml->XMLin("ship_order.xml");
此行会丢弃您创建的哈希引用,并将方法调用中的一个引用分配给$data
。
如果你关心项目的顺序(你可能不应该这样做,因为任何体面的XML格式都会包含一个告诉你顺序的属性),你需要使用一个返回一个对象的解析器,而不是数据结构。该对象将知道项目的顺序,并为您提供返回它们的children
方法。
或者,您可以自己构建数据结构:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $shipment;
my $t = XML::Twig->new(
twig_handlers => {
shiptoaddress => sub {
my ($t, $elt) = @_;
$shipment->{name} = $elt->first_child("name")->text;
$shipment->{address} = $elt->first_child("address")->text;
$t->purge;
},
items => sub {
my ($t, $elt) = @_;
push @{$shipment->{items}}, {
quantity => $elt->first_child("quantity")->text,
price => $elt->first_child("price")->text,
};
$t->purge;
},
},
);
$t->parse(join "", <DATA>); #FIXME: use parsefile later
use Data::Dumper;
print Dumper $shipment;
__DATA__
<?xml version="1.0" encoding="UTF-8" ?>
<shipment>
<shiptoaddress>
<name>Prasad</name>
<address>AnnaNagar</address>
</shiptoaddress>
<items>
<quantity>5</quantity>
<price>100</price>
</items>
<items>
<quantity>6</quantity>
<price>50</price>
</items>
<num_of_items>2</num_of_items>
</shipment>
答案 1 :(得分:3)
您可以考虑继承XML::Simple
并覆盖使用Tie::IxHash
创建哈希的必要方法。
但请认真考虑XML::Simple
的作者在此帖子中CPAN forum给出的答案:how to preserve XML::Simple element order ...
保留元素顺序不是,也永远不会是XML :: Simple的一个特性。对于某些XML文档类型,您可以通过继承XML :: Simple并覆盖new_hashref()方法来提供绑定到Tie :: IxHash的hashref。这可以解决ABC案件,但不会解决ABA案件。 简短的回答是,如果您关心元素顺序,那么您不应该使用XML :: Simple。 XML :: LibXML是一个很好的选择,对于许多用例而言,实际上并不比XML :: Simple更难使用 - 如[1]中所述
还有他在code中的内容:
##############################################################################
# Method: new_hashref()
#
# This is a hook routine for overriding in a sub-class. Some people believe
# that using Tie::IxHash here will solve order-loss problems.
#
sub new_hashref {
my $self = shift;
return { @_ };
}