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

Hi Monks,
I need to use XML::XPath to do some numbers matching in this XML file that is inside of a zip file. I know if a treat the XML file as a text file I can, but I need to treat the file as XML for validation propose. My problem is here:
# After getting the XML file in @xml, how can I use it on the next lin +e. my @xml = $zip->membersMatching( '.*\.XML' ); # here is the issue! my $xml_file = XML::XPath->new(ioref => @xml);
Is that a way to do this, I have a sample code that shows what I am trying g to accomplish.
#!/usr/bin/perl use strict; use warnings; use Archive::Zip; use XML::XPath; my @numberstocheck = qw(112334 999888 222333 999888 0008877 003344 122 +2334 00009 004443 999888); my $zipfile = "test.zip"; my $zip = Archive::Zip->new( $zipfile ) || die; my @xml = $zip->membersMatching( '.*\.XML' ); my $xmlfile = XML::XPath->new(ioref => @xml); foreach my $row ($xmlfile->findnodes('/alllist')) { my $nodeset = $row->find('phnumbers'); foreach my $node ( $nodeset->get_nodelist ) { my $numbers = $node->find( 'numbers')->string_value; print "\n 19 - $numbers \n"; foreach (@numberstocheck) { if (/^($numbers)/g) { print "$numbers - ".$_."\n"; } } } }
Thanks a lot!

Replies are listed 'Best First'.
Re: Open a zip file content question!
by Anonymous Monk on Mar 04, 2011 at 01:14 UTC
    Well, membersMatching only returns filenames
    my @xml = $zip->membersMatching( '.*\.XML' ); my $xmlfile = XML::XPath->new(ioref => @xml);
    And ioref expects filehandles

    You have to give the functions what they want :)

      Yes, and that's where I am stuck, any code I can see on how this could be accomplished? Thanks!
        use Archive::Zip::MemberRead; my $xmlfile = XML::XPath->new(ioref => $xml[0]->readFileHandle );
Re: Open a zip file content question!
by Anonymous Monk on Mar 04, 2011 at 14:44 UTC
    #!/usr/bin/perl -- use strict; use warnings; use Archive::Zip; use XML::XPath; use autodie qw' chdir unlink '; Main( @ARGV ); exit( 0 ); sub Main { ( undef, my $zipfile ) = Archive::Zip::tempFile(); my $fillThisFile = "$zipfile-junk.xml"; { my $zip = Archive::Zip->new(); $zip->addString('c' x 300, 'bunchOfCs.txt'); $zip->addString(q~<r><a href="#">#</a> <a href="#1">#1</a></r>~, 'test.xml'); $zip->writeToFileNamed( $zipfile ); } { my $zip = Archive::Zip->new( $zipfile ); my @xml = $zip->membersMatching( '.*\.xml' ); $zip->extractMember( $xml[0] , $fillThisFile ); my $xml = XML::XPath->new(filename => $fillThisFile); for my $node ( $xml->find('//a')->get_nodelist) { print $node->toString ,"\n"; } } unlink $zipfile, $fillThisFile; } __END__ <a href="#">#</a> <a href="#1">#1</a>
      Thanks to this last posting, I got the problem solved!!!
      #!/usr/bin/perl use strict; use warnings; use Archive::Zip; use XML::XPath; my @numberstocheck = qw(112334 999888 222333 999888 0008877 003344 122 +2334 00009 004443 999888); my $zipfile = "test.zip"; my $fillThisFile = "$zipfile-junk.xml"; my $zip = Archive::Zip->new( $zipfile ) || die; my @xml = $zip->membersMatching( '.*\.XML' ); $zip->extractMember( $xml[0] , $fillThisFile ); my $xmlfile = XML::XPath->new(filename => $fillThisFile); foreach my $row ($xmlfile->findnodes('/alllist')) { my $nodeset = $row->find('phnumbers'); foreach my $node ( $nodeset->get_nodelist ) { my $numbers = $node->find( 'numbers')->string_value; print "\n 19 - $numbers \n"; foreach (@numberstocheck) { if (/^($numbers)/g) { print "$numbers - ".$_."\n"; } } } }

      Thanks a lot for that!