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

Hi Monks!

I am stuck here, I have a direcory with about 40 xml files, I need to parse these files all at once, or by a range from a select dropdown menu, I have the code to go to the direcory and search for the files I need. But on the next step is where I am having a problem, how to pass the range of files and use it with this line,

my $xp = XML::XPath->new(filename => $x_file);

Is it possible? How could I do that?
I got it to work with one file, but now that I have this much more files I am kind of lost.
I think I need to pass these files into an array or something, using a range between to first file till the last one selected, any help will be great!!!!
Thank you!!!

#!/perl/bin/perl #use strict; #commented out for testing propose only use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); use DBI; use XML::XPath; use XML::XPath::XMLParser; my $q = new CGI; print header(); my $transac = $q->param('transac'); my $get_file_from = $q->param('get_file_from'); my $get_file_to = $q->param('get_file_to'); if($transac eq "parse_now"){ &parse_now; }else{ &main; } sub main{ print "Start Main:<br><br>"; print " <table border=\"1\" width=\"600\" cellspacing=\"0\" cellpadding +=\"0\"> <tr><form name=\"xmlform\" action=\"get_node.pl\" method=\"GET +\"> <input type=\"hidden\" name=\"transac\" value=\"parse_now\ +"> <td>Check Policies from:&nbsp;&nbsp;&nbsp;&nbsp;</td> <td><div align=\"center\"> <select name=\"get_file_from\">"; my $dir = '/xml'; opendir(DIR, $dir) or die $!; while (my $file = readdir(DIR)) { # We only want files next unless (-f "$dir/$file"); # Use a regular expression to find files ending in .xml next unless ($file =~ m/\.xml$/); # change to the date format if needed $file=~/(.*?)_(\d{4})(\d{2})(\d{2})_(.*?)/; my $year= $2; my $month= $3; my $day = $4; print "<option value=\"$file\">$file</option>"; } closedir(DIR); #exit; print " </select> </td> <td>&nbsp;&nbsp;&nbsp;to&nbsp;&nbsp;&nbsp;</td> <td><div align=\"center\"> <select name=\"get_file_to\">"; my $dir = '/xml'; opendir(DIR, $dir) or die $!; while (my $file = readdir(DIR)) { # We only want files next unless (-f "$dir/$file"); # Use a regular expression to find files ending in .xml next unless ($file =~ m/\.xml$/); # change to the date format if needed later $file=~/(.*?)_(\d{4})(\d{2})(\d{2})_(.*?)/; my $year= $2; my $month= $3; my $day = $4; print "<option value=\"$file\">$file</option>"; } closedir(DIR); #exit; print " </select> </td> </tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td> <td>&nbsp;</td> <td align=\"right\"><input type=\"submit\" value=\"Send\"></td> </tr></div> </table></form>"; } # End Sub Main sub parse_now{ # change to the date format if needed later $get_file_from=~/(.*?)_(\d{4})(\d{2})(\d{2})_(.*?)/; my $year= $2; my $month= $3; my $day = $4; my $x_file = "/xml/$get_file_from"; my $xp = XML::XPath->new(filename => $x_file); # more stuff here ........ exit; } #end sub parse now

Replies are listed 'Best First'.
Re: Range File Open
by stiller (Friar) on Mar 04, 2008 at 14:17 UTC
    If you have an array of files:
    for my $x_file (@files){ my $xp = XML::XPath->new(filename => $x_file); # continue as before }
      OK, but how can I pass the range of files to be open to this array?

        You already have some code to scan through your directory and decide whether or not you want a file, so all you have to do is push the file into the array at the end of a similar loop. Something like the following:

        while (my $file = readdir(DIR)) { #decide whether or not this is a file the user wants ... push @files, $file; }

        Then you can use stiller's loop to iterate through that list, opening each file for processing.

        Edit: amarquis idea is better than the following, I didn't look through your code to notice what he saw....

        you could use

        my @files; if (-d $x_file) { # $x_file is a directory, not a file @files = glob "$x_file/*xml"; } elsif ($x_file =~ /xml$/ and -e $x_file){ # $x_file is an xml-file, and we have access to it push @files, $x_file; } else { die("can't make sense out xml-directory or xml-file $x_file"); }
        Or File::Glob, File::Find, ...
Re: Range File Open
by Anonymous Monk on Mar 04, 2008 at 15:37 UTC
    What about something like that:

    my $dir = '/xml'; my @all_files; opendir(DIR, $dir) or die $!; while (my $file = readdir(DIR)) { next if ($file =~ m/^\./); next unless ($file =~ m/\.xml$/); push @all_files, $file; } closedir(DIRHANDLE); #Get the range using a slice here, can be values coming from the dropd +own menu"; my $from = "0"; my $to = "1"; my @new_all_files = @all_files[$from,$to]; my $open_this; for my $x_file (@new_all_files){ ...stuff }
Re: Range File Open
by Jenda (Abbot) on Mar 05, 2008 at 23:08 UTC
    if($transac eq "parse_now"){ &parse_now; }else{

    Do NOT use &subroutine; unless you really do know what it does and really do need that behaviour! You don't and you don't. If you want to call a subroutine with no parameters use subroutine(); or just subroutine;. The & has a very special meaning there.

    print " <table border=\"1\" width=\"600\" cellspacing=\"0\" cellpadding +=\"0\"> <tr><form name=\"xmlform\" action=\"get_node.pl\" method=\"GET +\"> <input type=\"hidden\" name=\"transac\" value=\"parse_now\ +"> <td>Check Policies from:&nbsp;&nbsp;&nbsp;&nbsp;</td> <td><div align=\"center\"> <select name=\"get_file_from\">";

    Isn't this a bit ... ugly? Things like this may be necessary in C, but definitely not in Perl. Use either the qq{} quote-like operator or heredocs:

    print qq{ <table border="1" width="600" cellspacing="0" cellpadding="0"> <tr><form name="xmlform" action="get_node.pl" method="GET"> <input type="hidden" name="transac" value="parse_now"> <td>Check Policies from:&nbsp;&nbsp;&nbsp;&nbsp;</td> <td><div align="center"> <select name="get_file_from">}; #or print <<"*END*"; <table border="1" width="600" cellspacing="0" cellpadding="0"> <tr><form name="xmlform" action="get_node.pl" method="GET"> <input type="hidden" name="transac" value="parse_now"> <td>Check Policies from:&nbsp;&nbsp;&nbsp;&nbsp;</td> <td><div align="center"> <select name="get_file_from"> *END*