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

When I run the below mentioned code I don't get anything on stdout, I don't understand why parXML function not parsing each file and outputting data, undermentioned code this is just a part of whole script. Also my script does not shows any syntax error,it runs through with no output,Please help thanks!!

I want to output specific rows from xml stored in multiple files

I have stored files in an array

@array = `ls file* | awk '{print \$0}'`;

result of above code I am getting

file1 file2

Now I pass each file using foreach loop to parXML function

foreach (@array) { parXML($_); }

parXML function

sub parXML { my $file = shift; #print "$file\n"; my $twig=XML::Twig->new(twig_handlers => {IP_ADDRESS => \&ip, COM= +>\&co}); $twig->set_pretty_print('indented'); $twig->parsefile($file); sub ip { my($twig, $ip)= @_; print "Target:".$ip->text."\n"; twig->print; $twig->purge; } sub co { my($twig, $co)= @_; $co->print; print "\n\n"; $twig->purge; } }

xml stored in file1 and file2

<REP>abc</REP> <ING>ip</ING> <IP_ADDRESS>192.168.67.16</IP_ADDRESS> <COM> <DS> <N>1</N> </DS> </COM> <LIST>ac</LIST>
<REP>ab</REP> <ING>ip</ING> <IP_ADDRESS>192.168.67.110</IP_ADDRESS> <COM> <DS> <N>5</N> </DS> </COM> <LIST>gn</LIST>

Result I am looking for in output

<IP_ADDRESS>192.168.67.16</IP_ADDRESS> <COM> <DS> <N>1</N> </DS> </COM>
<IP_ADDRESS>192.168.67.110</IP_ADDRESS> <COM> <DS> <N>5</N> </DS> </COM>

Replies are listed 'Best First'.
Re: Processing xml data in multiple files using XML::Twig and outputting in a file
by toolic (Bishop) on Apr 25, 2011 at 17:56 UTC
    • Didn't you get a Can't locate object method "print" via package "twig" warning (on STDERR)? twig->print; should be $twig->print;
    • I had to add root tags to your input files (again) to make them valid XML (I named them "top").
    • I changed twig_handlers to twig_roots to remove desired tags from your output (see XML::Twig).
    • I moved your ip/co subs outside of your parXml sub. This does not change the functionality, but I see no reason to declare a sub within a sub here.
    use warnings; use strict; use XML::Twig; my @array = qw(file1 file2); foreach (@array) { parXML($_); } sub parXML { my $file = shift; #print "$file\n"; my $twig=XML::Twig->new(twig_roots => {IP_ADDRESS => \&ip, COM=>\& +co}); $twig->set_pretty_print('indented'); $twig->parsefile($file); } sub ip { my($twig, $ip)= @_; print "Target:".$ip->text."\n"; $twig->print; $twig->purge; } sub co { my($twig, $co)= @_; $co->print; print "\n\n"; $twig->purge; } __END__ Output to STDOUT: Target:192.168.67.16 <top> <IP_ADDRESS>192.168.67.16</IP_ADDRESS> </top> <COM> <DS> <N>1</N> </DS> </COM> Target:192.168.67.110 <top> <IP_ADDRESS>192.168.67.110</IP_ADDRESS> </top> <COM> <DS> <N>5</N> </DS> </COM>

    On a side note, you can probably replace:

    @array = `ls file* | awk '{print \$0}'`;
    with:
    @array = glob 'file*';