2012-08-23 49 views
0

Hy, 我想写一个目录中的所有文件和所有子目录到一个关联数组,并从这个aray创建一个XML。这是我的代码。Perl XML ::简单写目录

use strict; 
use warnings; 

use File::Find; 
use Data::Dumper; 
use XML::Simple; 

my $base_dir = '.'; 

my $xs = new XML::Simple; 
my %filelist; 

find(\&print_name_if_dir, $base_dir); 

sub print_name_if_dir 
{ 
    if (-f $_) { 
     $filelist{$File::Find::name}{size}=-s $_; 
     $filelist{$File::Find::name}{time}=(stat $_)[9]; 
    } 
} 

print Dumper(\%filelist); 
my $xml = $xs->XMLout(\%filelist, keyattr => "filename"); 
print $xml; 

,这是我的输出:

$VAR1 = { 
      './out.log' => { 
          'size' => 51, 
          'time' => 1345720984 
         }, 
      './foo/bat.txt' => { 
           'size' => 24, 
           'time' => 1345708287 
          }, 
      './test.pl' => { 
          'size' => 438, 
          'time' => 1345720762 
         } 
     }; 
<opt> 
    <./out.log size="51" time="1345720984" /> 
    <./foo/bat.txt size="24" time="1345708287" /> 
    <./test.pl size="438" time="1345720762" /> 
</opt> 

数组是好的,但XML应该是这样的:

<file name="bla.txt"> 
    <time>"1234"</time> 
    <size>"1234"</size> 
</file> 

请帮助我。

回答

1

XML::Simple很好,很简单。它的文档甚至自己也这么说。你无法从中得到任何可以想象的输出形式,而你很可能不可能。

但是,您可以比现在更接近您的位置,这种存储结构:

my $files = { 
    file => [ 
    { name => 'chunky.txt', time => 12345, size => 321 }, 
    { name => 'bacon.dat', time => 47123, size => 222 }, 
    ], 
}; 

这将导致下面的输出(通过print XMLout($files)):

<opt> 
    <file name="chunky.txt" size="321" time="12345" /> 
    <file name="bacon.dat" size="222" time="47123" /> 
</opt> 

什么是不可能的,在我看来,迫使timesize是儿童,而不是输出属性。

哦,这样的结构可以很容易地用下面的代码内置:

my %filelist = (file => []); 

sub print_name_if_dir { 
    return unless -f; 

    push @{ $filelist{file} }, { 
    name => $_, 
    size => -s $_, 
    time => (stat $_)[9], 
    }; 
} 
+0

非常感谢你!你知道我怎么可以在这个数组中搜索一个特定的文件名而没有循环,然后访问它的属性? – AndyH

+0

没有循环?您可以简单地将'print_name_if_dir'中创建的哈希引用存储到第二个哈希文件名中(我们称之为'%filerefs')。添加这个作为'print_name_if_dir'中的最后一行:'$ filerefs {$ _} = $ filelist {file} - > [ - 1];' –

+0

不错!谢谢你,莫里茨。 – AndyH