分类: Python/Ruby
2011-11-30 18:39:00
限制
XML::Simple 有两个主要限制。
1. 在输入方面,它将完整的XML文件读入内存,所以如果文件非常大或者需要处理XML数据流,就不能使用这个模块。
经验规则是,XML被读入内存时它会扩大10倍。如果有几百MB空闲内存,那么XML::Simple能够处理文件大小最多为几十MB。
2. 它无法处理 XML 混合内容,也就是在一个元素体中同时存在文本和子元素的情况
host.xml
10.0.0.101
10.0.1.101
10.0.0.102
10.0.0.103
10.0.1.103
# 读取host.xml文件
use XML::Simple;
my $file = '/etc/host.xml';
my $simple = XML::Simple->new();
# ForceArray => 1 仅有一个元素也要使用ARRAY,默认是HASH,KeepRoot => 1 通告XMLout()数据结构已经包含根元素名
my $ref = $simple->XMLin($file);
# 打印数据结构
use Data::Dumper;
print Dumper($ref);
# ref数据结构
$VAR1 = {
'debugfile' => '/tmp/foo.debug',
'server' => {
'kalahari' => {
'osversion' => '2.0.34',
'osname' => 'linux',
'address' => [
'10.0.0.103',
'10.0.1.103'
]
},
'sahara' => {
'osversion' => '2.6',
'osname' => 'solaris',
'address' => [
'10.0.0.101',
'10.0.1.101'
]
},
'gobi' => {
'osversion' => '6.5',
'osname' => 'irix',
'address' => '10.0.0.102'
}
},
'logdir' => '/var/log/foo/'
};
遍历元素
#!/usr/bin/perl
use XML::Simple;
use Data::Dumper;
my $file = '/tmp/config.xml';
my $simple = XML::Simple->new( ForceArray => 1, KeepRoot => 1 );
my $ref = XMLin($file);
print Dumper($ref);
foreach my $tag1 ( keys %$ref ) {
if ( $ref->{$tag1} =~ /^HASH/ ) {
print "$tag1: " . "\n";
foreach my $tag2 ( keys %{ $ref->{$tag1} } ) {
if ( $ref->{$tag1}->{$tag2} =~ /^HASH/ ) {
print " $tag2: " . "\n";
foreach my $tag3 ( keys %{ $ref->{$tag1}->{$tag2} } ) {
if ( $ref->{$tag1}->{$tag2}->{$tag3} =~ /^ARRAY/ ) {
print " $tag3: " . "\n";
foreach my $tag4 ( @{ $ref->{$tag1}->{$tag2}->{$tag3} } ) {
print " $tag4 " . $ref->{$tag1}->{$tag2}->{$tag3}->[$tag4] . "\n";
}
} else {
print " $tag3 => " . $ref->{$tag1}->{$tag2}->{$tag3} . "\n";
}
}
} else {
print "$tag2 => " . $ref->{$tag1}->($tag2) . "\n";
}
}
} else {
print "$tag1 => " . $ref->{$tag1} . "\n";
}
}
# perl xml.pl
debugfile => /tmp/foo.debug
server:
kalahari:
osversion => 2.0.34
osname => linux
address:
10.0.0.103
10.0.1.103
sahara:
osversion => 2.6
osname => solaris
address:
10.0.0.101
10.0.1.101
gobi:
osversion => 6.5
osname => irix
address => 10.0.0.102
logdir => /var/log/foo/
更新XML
#!/usr/bin/perl
use strict;
use XML::Simple;
use Data::Dumper;
my $file = '/tmp/config.xml';
my $simple = XML::Simple->new( ForceArray => 1 );
my $ref = $simple->XMLin($file);
print Dumper($ref);
$ref->{server}->{gobi}->{address}->[1] = '10.0.1.102';
print Dumper($ref);
$simple->XMLout($ref, OutputFile => '/tmp/config.fix.xml', XMLDecl => "" );# ForceArray => 1 选项,强制同一层仅1个元素时也使用array类型,比较上面例子的Dumper输出
$VAR1 = {
'debugfile' => '/tmp/foo.debug',
'server' => {
'kalahari' => {
'osversion' => '2.0.34',
'osname' => 'linux',
'address' => [
'10.0.0.103',
'10.0.1.103'
]
},
'sahara' => {
'osversion' => '2.6',
'osname' => 'solaris',
'address' => [
'10.0.0.101',
'10.0.1.101'
]
},
'gobi' => {
'osversion' => '6.5',
'osname' => 'irix',
'address' => [
'10.0.0.102',
'10.0.1.102'
]
}
},
'logdir' => '/var/log/foo/'
};# cat /tmp/config.fix.xml
10.0.0.102
10.0.1.102
10.0.0.103
10.0.1.103
10.0.0.101
10.0.1.101
AndroidManifest.xml 例子:
#!/usr/bin/perl
use strict;use XML::Simple;
use Data::Dumper;my $file=`java -jar AXMLPrinter2.jar AndroidManifest.xml`;
my $simple = new XML::Simple;
#my $simple = XML::Simple->new( ForceArray => 1, KeepRoot => 1 );
my $ref = XMLin($file);print Dumper($ref);
foreach my $tag1 ( keys %$ref ) {
if ( $ref->{$tag1} =~ /^HASH/ ) {
foreach my $tag2 ( keys %{ $ref->{$tag1} } ) {
#print "tag2 $tag2\n";
if ( $ref->{$tag1}->{$tag2} =~ /^ARRAY/ ) {
foreach my $tag3 (@{ $ref->{$tag1}->{$tag2} } ) {
if ( $tag3 =~ /^HASH/ ) {
foreach my $tag4 ( keys %{$tag3} ) {
#print "$tag4 => $tag3->{$tag4}\n";
if ($tag3->{$tag4}=~/^HASH/) {
foreach my $tag5 (keys %{$tag3->{$tag4}}) {
#print "$tag5 $tag3->{$tag4}->{$tag5}\n";
if ($tag3->{$tag4}->{$tag5}=~/^ARRAY/) {foreach my $tag6 ( @{ $tag3->{$tag4}->{$tag5} } ) {
if ({$tag6}=~/^HASH/) {
foreach my $tag7 (keys %{$tag6}) {if ($tag6->{$tag7} eq "android.intent.action.MAIN") {
print "MAIN Name => $tag6->{$tag7}\n";
#print "$ref->{$tag1}->{$tag2}";
#print "tag4 $tag3\n";
print "Activity Name =>$tag3->{\"android:name\"}\n";
}
}
}
}
}elsif ($tag3->{$tag4}->{$tag5}=~/^HASH/) {
#print "$tag5 $tag3->{$tag4}->{$tag5}\n";
foreach my $lag6 (keys %{$tag3->{$tag4}->{$tag5}}) {#print "$lag6 $tag3->{$tag4}->{$tag5}->{$lag6}\n";
if ($tag3->{$tag4}->{$tag5}->{$lag6} eq "android.intent.action.MAIN") {print "MAIN Name => $tag3->{$tag4}->{$tag5}->{$lag6}\n";
#print "$ref->{$tag1}->{$tag2}";
#print "tag4 $tag3\n";
print "Activity Name =>$tag3->{\"android:name\"}\n";
}
}
}
}
}
}
}
}
}elsif ( $ref->{$tag1}->{$tag2} =~ /^HASH/ ) {
foreach my $label3(keys %{$ref->{$tag1}->{$tag2}}) {
#print "$label3=> $ref->{$tag1}->{$tag2}->{$label3}\n";if ( $ref->{$tag1}->{$tag2}->{$label3}=~/^HASH/) {
#print "$label3\n";
foreach my $label4 (keys %{$ref->{$tag1}->{$tag2}->{$label3}}) {#print "$label4 => $ref->{$tag1}->{$tag2}->{$label3}->{$label4}\n";
if ( $ref->{$tag1}->{$tag2}->{$label3}->{$label4}=~/^HASH/) {
foreach my $label5 (keys %{$ref->{$tag1}->{$tag2}->{$label3}->{$label4}}) {
#print "$label5 => $ref->{$tag1}->{$tag2}->{$label3}->{$label4}->{$label5}\n";
if ($ref->{$tag1}->{$tag2}->{$label3}->{$label4}->{$label5} eq "android.intent.action.MAIN") {print "MAIN Name => $ref->{$tag1}->{$tag2}->{$label3}->{$label4}->{$label5}\n";
#print "$ref->{$tag1}->{$tag2}";
#print "tag4 $tag3\n";
print "Activity Name =>$ref->{$tag1}->{$tag2}->{\"android:name\"}\n";
}
}
}}
}
}
}
}
}
}