in reply to Re: How to read a file containing filenames and pass as input to perl script?
in thread How to read a file containing filenames and pass as input to perl script?

@Choroba, Thanks, I tried the code as you suggested, but getting the error as
Can't call method "text" on an undefined value at IDOCXML_parse2.pl li +ne 27, <$list> line 1. at IDOCXML_parse2.pl line 23 at IDOCXML_parse2.pl line 23
Let me know what I'm missing. Thanks! The code is
#!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; use XML::Twig; my $listfile = shift; open my $list, '<', $listfile or die $!; while (my $xmlfile = <$list>) { chomp $xmlfile; my $twig = XML::Twig->new( twig_handlers => { 'EDI_DC40' => \&process_EDI_DC40, }, ); my $csv = Text::CSV_XS->new({ 'sep_char' => "|", }); $twig->parsefile($xmlfile); sub process_EDI_DC40 { my( $twig, $thingy ) = @_; my @values = map { $thingy->first_child( $_ )->text } qw(DOCNUM MESTYP SNDPRN RCVPOR RCVPRN); $csv->say( *STDOUT, \@values ); } }

Replies are listed 'Best First'.
Re^3: How to read a file containing filenames and pass as input to perl script?
by choroba (Cardinal) on Apr 20, 2018 at 12:59 UTC
    Somewhere in the data, there's an EDI_DC40 element that doesn't have all the child nodes. You need to check whether the child exists before calling a method on it:
    my @values = map { my $ch = $thingy->first_child( $_ ); $ch ? $ch->text : "" } qw( DOCNUM MESTYP SNDPRN RCVPOR RCVPRN );

    Also, as I mentioned, you probably don't need to create a new Twig and CSV objects for each file. Declaring the sub inside the loop makes no sense, either.

    #!/usr/bin/perl use warnings; use strict; use Text::CSV_XS; use XML::Twig; my $csv = 'Text::CSV_XS'->new({ sep_char => '|', }); sub process_EDI_DC40 { my ($twig, $thingy) = @_; my @values = map { my $ch = $thingy->first_child( $_ ); $ch ? $ch->text : "" } qw( DOCNUM MESTYP SNDPRN RCVPOR RCVPRN ); $csv->say(*STDOUT, \@values); } my $listfile = shift; open my $list, '<', $listfile or die $!; my $twig = 'XML::Twig'->new( twig_handlers => { EDI_DC40 => \&process_EDI_DC40, }, ); while (my $xmlfile = <$list>) { chomp $xmlfile; $twig->parsefile($xmlfile); }

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Thanks, that works like a charm! One last question - I'm also trying to prefix every line in the output pipe separated file with this text "XML". I tried this, on the while loop right before the chomp, but the substitution isn't working as expected.
      $xmlfile =~ 's/^/XML|/' ;
      Where do i insert the above line in the code for the prefixing to work?
      while (my $xmlfile = <$list>) { $xmlfile =~ 's/^/XML|/' ; chomp $xmlfile; $twig->parsefile($xmlfile); }
        $xmlfile =~ 's/^/XML|/' ;

        Omit the quotes:

        $xmlfile =~ s/^/XML|/;
        prefix every line in the output pipe separated file

        Use unshift to add 'XML' to the front of @values array

        sub process_EDI_DC40 { my ($twig, $thingy) = @_; my @values = map { my $ch = $thingy->first_child( $_ ); $ch ? $ch->text : "" } qw( DOCNUM MESTYP SNDPRN RCVPOR RCVPRN ); unshift @values,'XML'; # add $csv->say(*STDOUT, \@values); }
        poj