更改目录并获取xml文件以解析perl中的某些数据

时间:2012-06-08 15:20:55

标签: perl

我正在尝试解析位于一个目录的子目录中的特定XML文件。由于某种原因,我收到错误说文件不存在。如果文件不存在,则应该转到下一个子目录。

这是我的代码

        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

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分: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");