我如何维护XML文件中的值的顺序,并使用XML :: Simple读取它?
我正在使用XML :: Simple来解析XML文件。代码给出了下面的XML文件,我如何维护XML文件中的值的顺序,并使用XML :: Simple读取它?
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>
输出不是为了未来,尽管我使用领带:: IxHash模块。
我的输出:
$VAR1 = {
'num_of_items' => '2',
'shiptoaddress' => {
'name' => 'Prasad',
'address' => 'AnnaNagar'
},
'items' => [
{
'quantity' => '5',
'price' => '100'
},
{
'quantity' => '6',
'price' => '50'
}
]
};
啊,但你不使用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>
您的条款“任何体面的XML格式将包含告诉您订单的属性”是非常错误的。 _XML本身默认为被订购._ – 2015-02-05 11:35:49
你可以考虑继承XML::Simple
和overwritting创建与Tie::IxHash
哈希必要的方法。
但是认真考虑这个答案由XML::Simple
笔者在此线程CPAN forum给出:how to preserve XML::Simple element order ...
保留元素的顺序是不是也永远不会是XML的一个特点::简单。对于某些XML文档类型,您可以通过继承XML :: Simple并重写new_hashref()方法来提供与Tie :: IxHash绑定的hashref。这可以解决ABC案件,但它不会解决ABA案件。 简短的回答是,如果你关心元素顺序,那么你不应该使用XML :: Simple。 XML ::的libxml是一个很好的替代这对于很多使用情况实在是没有难度比XML使用::简单 - 在[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 { @_ };
}
看到http://stackoverflow.com/questions/3650229/parsing-xml-file-in-perl-retain-sequence/3650297#3650297 – 2010-09-13 15:08:23
当XML ::简单并不做你想要的东西,不要使用XML :: Simple。也就是说,当你使用* :: Simple模块来尝试做某件事情时,它不会这么做,这已经不再简单了。 – 2010-09-18 10:06:58