App-xml_grep2

 view release on metacpan or  search on metacpan

lib/App/Xml_grep2.pm  view on Meta::CPAN

          { my $set= $self->grep_text( $xpath, $file) or next;
            if( @$set)
              { 
                if( $need_filename) { foreach (@$set) { s{^}{$file:} } } # add filename
                print @$set;
              }
          }
        elsif( $self->{count})
          { my $nb= $self->grep_nb( $xpath, $file);
            if( !defined $nb) { next; }
            print $need_filename ? "$file:$nb\n" : "$nb\n"; 
          }
        else
          { # regular mode
            my $nodes= $self->grep_nodes( $xpath, $file) or next;
            if( @$nodes)
              { if( $header) 
                  { if( $self->{original_encoding}) 
                      { my $encoding= $nodes->[0]->ownerDocument->encoding;
                        if( $encoding) { $header=~ s{UTF-8}{$encoding}; }
                      }
                    print $header; 
                    $header= '';
                  }

                if( $need_file_wrapper)
                  { print $self->file_header( $file);
                    $self->_print_hits_in_file( 2 => $nodes);
                    print $self->file_footer(),
                          ;
                  }
                else
                  { $self->_print_hits_in_file( 1 => $nodes); }

                $got_result=1;
              }
          }         
      }
    
    if( $self->{quiet}) { return -1; }
    
    if( $header && $self->{generate_empty_set})                  { print $header; } # in case no result was found
    if( $footer && ($got_result || $self->{generate_empty_set})) { print $footer; }
    
    return 0;
  }

# the print is done here to avoid passing a potentially pretty big string around
sub _print_hits_in_file
  { my( $self, $format, $nodes)= @_;
    print map( { $self->{format} ? $self->indented_xml( $_->toString( $self->{format}, $self->{original_encoding}), $format)  . "\n"
                                                 : $_->toString( 0, $self->{original_encoding}) . "\n"
                               } @$nodes
                              );
  } 
      
sub file_list
  { my $self= shift;
    my $rules= File::Find::Rule->new;
    if( $self->{include}) { $rules->name( $self->{include});     }
    if( $self->{exclude}) { $rules->not_name( $self->{exclude}); }
    unless( $self->{recursive})   { $rules->maxdepth( 0);                }
    $rules->not_directory();
    my @files= $rules->in( @_);
    return @files;
  }


sub grep_nodes
  { my( $self, $xpath, $file)= @_;
    my( undef, @nodes)= $self->findnodes( $file => $xpath) or return ;
    if( $self->{max_count }&& (@nodes >= $self->{max_count})) { $#nodes= $self->{max_count }-1; }
    return \@nodes;
  }

sub grep_v
  { my( $self, $xpath, $file)= @_;
    my( $doc, @nodes)= $self->findnodes( $file => $xpath) or return ;
    foreach my $node (@nodes)
      { my $parent= $node->parentNode or return;
        $parent->removeChild( $node);
      }
    return $doc;
  }


sub findnodes
  { my( $self, $file, $xpath)= @_;

    my $doc;


    if( defined $file)
      { # need to test this instead of calling parse_*_file, or we get an untrappable "I/O error : Permission denied" 
        # message from XML::LibXML
        if( ! -e $file) 
          { $self->mwarn( "xml_grep2: $file: No such file or directory"); 
            return;
          } 
        elsif( ! -r $file) 
          { $self->mwarn( "xml_grep2: $file: Permission denied"); 
            return;
          } 
      }

    my( $method, @parse_args);

    if( $XML::LibXML::VERSION > 1.70 && ! $self->{xl})
      { $method    = $self->{html} ? 'load_html' : 'load_xml';
        @parse_args = defined $file ? ( location => $file) : ( IO => \*STDIN);
      }
    else
      { $method = $self->{html} ? 'parse_html' : 'parse'; 
        $method .= defined $file ? '_file' : '_fh'      ;
        @parse_args = defined $file ? $file : \*STDIN;
      }
        
    eval { $doc= $self->{parser}->$method( @parse_args); };
    if( $@) 
      { if( !$self->{no_messages}) 
          { $self->parsing_exception( $@); }
        return;
      }



( run in 1.173 second using v1.01-cache-2.11-cpan-ba708fea25c )