ATLien has asked for the wisdom of the Perl Monks concerning the following question:

I'm attempting to process multiple files - using a text based file list - using XML::XPath module. Processing one file works as advertised - but attempting to process multiple files, I get a "Cannot open file..." error on the first file in the list. Here is the code I'm using:

foreach $page (@files) { my $xp = XML::XPath->new(filename => $page); my $nodeset = $xp->find('//DCR'); # find all DCRs my @nodelist = $nodeset->get_nodelist; @dcrs = map {$_->string_value ? $_->string_value : ()} @nodeli +st; foreach my $dcr(@dcrs) { print "$dcr\n"; } }
and the file list is a simple text file like:

file1.xml
file2.xml
file3.xml

Any thoughts or ideas on this?

Replies are listed 'Best First'.
Re: XML::XPath and processing multiple files
by hdb (Monsignor) on Jul 15, 2013 at 14:40 UTC

    Have you chomped the filenames when reading them from the text file?

Re: XML::XPath and processing multiple files
by rjt (Curate) on Jul 15, 2013 at 14:41 UTC
    foreach $page (@files) { my $xp = XML::XPath->new(filename => $page);

    The salient bit here would be how you are generating @files. You say it is a "simple text file", but you don't show the code you use to read it in. Did you perhaps forget to chomp the lines? What's in the "..." in "Cannot open file..." (an important diagnostic message, perhaps)? As Corion suggests, can you guarantee the files in the list are actually valid to begin with?

      My apologies for not being complete. The file list is a manually created list of selected file paths. As far as whether or not they exist - if I pair the list down to just the first file - the script works fine. Here is the entire script:
      use XML::XPath; use XML::XPath::XMLParser; my $filelist = shift; #Process file list open(FILELIST, "$filelist") or die("Unable to open file"); my @files = <FILELIST>; close(FILELIST); foreach $page (@files) { my $xp = XML::XPath->new(filename => $page); my $nodeset = $xp->find('//DCR'); # find all DCRs my @nodelist = $nodeset->get_nodelist; #@dcrs = map($_->string_value, @nodelist); @dcrs = map {$_->string_value ? $_->string_value : ()} @nodeli +st; foreach my $dcr(@dcrs) { print "$dcr\n"; } }
      For some reason I thought I'd added chomp before and it didn't work:
      chomp($page);

        Most likely there is other whitespace at the end of your file names. Or maybe the "first" file exists in two places.

        Does the script still fail if you have the line with the first, existing file duplicated?

        chomp may not work if the filelist was manually created on a windows machine and you are running the script on unix. Suggest you try a regex instead.
        open(IN,'file.txt') or die "$!"; my @files = <IN>; foreach $page (@files) { $page =~ s/\s+$//g; print "parsing [$page]\n"; # code }
        poj
        Also the complete error is:

        Cannot open file 'file1.xml ' at /apps/interwoven/TeamSite/iw-perl/vendor/lib/XML/XPath.pm line 53.

Re: XML::XPath and processing multiple files
by Corion (Patriarch) on Jul 15, 2013 at 14:36 UTC

    How are you certain that the files actually exist? Maybe the error message is correct?

Re: XML::XPath and processing multiple files
by CountZero (Bishop) on Jul 15, 2013 at 15:17 UTC
    I tried a little test myself and I can reproduce the "Cannot open file ..." error by either not chomping the filename or by having the file not existing in the folder the script is looking at or by having a file that is not readable by the user or group that owns the script.

    The new method just performs a -e and -r file test on the argument of new.

    Do you provide the full file path in your list of files?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: XML::XPath and processing multiple files
by Laurent_R (Canon) on Jul 15, 2013 at 17:50 UTC

    If the file list was created under Windows and you working on Unix/Linux/Cygwin, chomp will not be enough. Try this:

    foreach $page (@files) { chomp $page; $page =~ s/\r//g; # ... }
    or possibly:
    <c>foreach $page (@files) { $page =~ s/[\r\n]//g; # ... }