2012-08-23 3 views
0

Hy, Я хочу записать все файлы в каталог и все подкаталоги в ассоциативный массив и создать XML из этого афера. вот мой код.Perl XML :: Simple write Directory

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> 

Что невозможно, на мой взгляд, заставляет time и size будут выводиться как дети вместо атрибутов.

О, такая структура легко может быть построена с помощью следующего кода:

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

Смежные вопросы