2012-06-08 28 views
1

我想解析位于一个目录的子目录中的特定XML文件。出于某种原因,我收到错误说文件不存在。如果文件不存在,它应该转到下一个子目录。更改目录并获取xml文件以解析perl中的某些数据

这里是我的代码

 use strict; 
     use warnings; 
     use Data::Dumper; 
     use XML::Simple; 

     my @xmlsearch = map { chomp; $_ } `ls`; 

     foreach my $directory (@xmlsearch) { 
      print "$directory \n"; 
      chdir($directory) or die "Couldn't change to [$directory]: $!"; 
      my @findResults = `find -name education.xml`; 

     foreach my $educationresults (@findResults){ 
      print $educationresults; 
      my $parser = new XML::Simple; 
      my $data = $parser->XMLin($educationresults); 
      print Dumper($data); 
      chdir('..');   
     } 

     } 

     ERROR 
     music/gitar/education.xml 
     File does not exist: ./music/gitar/education.xml 
+0

为什么不使用['使用File :: Find;'](http://perldoc.perl.org/File/Find.html)? – 2012-06-08 15:25:14

+0

您是否想要递归查找'education.xml'文件,还是仅查找这些目录? – TLP

+0

你好,我只是想找到一个教育目录到一个目录。所以主目录是音乐,可以说10个子目录。例如吉他,钢琴,鼓。我只想在音乐/吉他或音乐/钢琴下搜索。我不想在音乐/吉他/ dir1/dir2下搜索。 – Maxyie

回答

1

使用chdir你做的方式使代码IMO的可读性。您可以使用File::Find那个:

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

sub findxml { 
    my @found; 

    opendir(DIR, '.'); 
    my @where = grep { -d && m#^[^.]+$# } readdir(DIR); 
    closedir(DIR); 

    File::Find::find({wanted => sub { 
     push @found, $File::Find::name if m#^education\.xml$#s && -f _; 
    } }, @where); 
    return @found; 
} 

foreach my $xml (findxml()){ 
    say $xml; 
    print Dumper XMLin($xml); 
} 
0

当你发现自己依靠反引号执行shell命令,你应该考虑是否有perl正确的方式去做。在这种情况下,有。

ls可以替换为<*>,这是一个简单的glob。行:

my @array = map { chomp; $_ } `ls`; 

是说

chomp(my @array = `ls`); # chomp takes list arguments as well 

但当然,正确的方法是

my @array = <*>; # no chomp required 

现在只是一个迂回的方式,简单的解决方案,这一切仅仅是为了做

for my $xml (<*/education.xml>) { # find the xml files in dir 1 level up 

其中将覆盖一级目录,不带递归。对于全递归,使用File::Find

use strict; 
use warnings; 
use File::Find; 

my @list; 
find(sub { push @list, $File::Find::name if /^education\.xml$/i; }, "."); 

for (@list) { 
    # do stuff 
    # @list contains full path names of education.xml files found in subdirs 
    # e.g. ./music/gitar/education.xml 
} 

你应该注意到,改变目录不是必需的,在我的经验,不值得的麻烦。而不是做的:

chdir($somedir); 
my $data = XMLin($somefile); 
chdir(".."); 

简单地做:

my $data = XMLin("$somedir/$somefile"); 
+0

嘿谢谢你的回答,它有助于回溯到只有一个子目录。 :) – Maxyie

相关问题