perl XML::Simple 模块

发布时间:2020-08-26编辑:脚本学堂
perl 的 XML::Simple 有两个主要限制。1. 在输入方面,它将完整的XML文件读入内存,所以如果文件非常大或者需要处理XML数据流,就不能使用这个模块。

perl 的 XML::Simple 有两个主要限制。
1. 在输入方面,它将完整的XML文件读入内存,所以如果文件非常大或者需要处理XML数据流,就不能使用这个模块。
经验规则是,XML被读入内存时它会扩大10倍。如果有几百MB空闲内存,那么XML::Simple能够处理文件大小最多为几十MB。

2. 它无法处理 XML 混合内容,也就是在一个元素体中同时存在文本和子元素的情况
<example>of <mixed/> content</example>
host.xml
 

复制代码 代码如下:
<config logdir="/var/log/foo/" debugfile="/tmp/foo.debug">
    <server name="sahara" osname="solaris" osversion="2.6">
      <address>10.0.0.101</address>
      <address>10.0.1.101</address>
    </server>
    <server name="gobi" osname="irix" osversion="6.5">
      <address>10.0.0.102</address>
    </server>
    <server name="kalahari" osname="linux" osversion="2.0.34">
      <address>10.0.0.103</address>
      <address>10.0.1.103</address>
    </server>
</config>

# 读取host.xml文件
 

复制代码 代码如下:

use XML::Simple;
 
<pre escaped="true">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 => "<?xml version='1.0'?>" );

# 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
 

复制代码 代码如下:
<?xml version='1.0'?>
<opt debugfile="/tmp/foo.debug" logdir="/var/log/foo/">
  <server name="gobi" osname="irix" osversion="6.5">
    <address>10.0.0.102</address>
    <address>10.0.1.102</address>
  </server>
  <server name="kalahari" osname="linux" osversion="2.0.34">
    <address>10.0.0.103</address>
    <address>10.0.1.103</address>
  </server>
  <server name="sahara" osname="solaris" osversion="2.6">
    <address>10.0.0.101</address>
    <address>10.0.1.101</address>
  </server>
</opt>

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 $tag2n";
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 $tag3n";
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 $tag3n";
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 "$label3n";
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 $tag3n";
print "Activity Name =>$ref->{$tag1}->{$tag2}->{"android:name"}n";
}
}
}
}
}
}
}
}
}
}