Get content from the HTML tag using MyParser in Perl

advertisements

I have a html as the following:

<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body bgcolor="white">

<h1>foo.c</h1>

<form method="post" action=""
        enctype="application/x-www-form-urlencoded">
  Compare this file to the similar file:
  <select name="file2">

    <option value="...">...</option>

  </select>
  <input type="hidden" name="file1" value="foo.c" /><br>
  Show the results in this format:
</form>
<hr>

<p>
<pre>
some code
</pre>

I need to get value of input name = 'file' and the contents of HTML pre tag. I don't know on perl language, by googling I wrote this small program(that I believe isn't "elegant"):

#!/usr/bin/perl

package MyParser;
use base qw(HTML::Parser);

#Store the file name and contents obtaind from HTML Tags
my($filename, $file_contents);

#This value is set at start() calls
#and use in text() routine..
my($g_tagname, $g_attr);

#Process tag itself and its attributes
sub start {
    my ($self, $tagname, $attr, $attrseq, $origtext) = @_;

    $g_tagname = $tagname;
    $g_attr = $attr;
}

#Process HTML tag body
sub text {
    my ($self, $text) = @_;

    #Gets the filename
    if($g_tagname eq "input" and $g_attr->{'name'} eq "file1") {
    $filename = $attr->{'value'};
    }

    #Gets the filecontents
    if($g_tagname eq "pre") {
    $file_contents = $text;
    }
}

package main;

#read $filename file contents and returns
#note: it works only for text/plain files.
sub read_file {
    my($filename) = @_;
    open FILE, $filename or die $!;
    my ($buf, $data, $n);
    while((read FILE, $data, 256) != 0) {
    $buf .= $data;
    }
    return ($buf);
}

my $curr_filename = $ARGV[0];
my $curr_file_contents = read_file($curr_filename);

my $parser = MyParser->new;
$parser->parse($curr_file_contents);

print "filename: ",$filename,"file contents: ",$file_contents;

Then I call ./foo.pl html.html But I'm getting empty values from $filename and $file_contents variables.

How to fix this? suggestion to improve the code is very appreciated too.


Like always, there's more than one way to do it. Here's how to use the DOM Parser of Mojolicious for this task:

#!/usr/bin/env perl

use strict;
use warnings;
use Mojo::DOM;

# slurp all lines at once into the DOM parser
my $dom = Mojo::DOM->new(do { local $/; <> });

print $dom->at('input[name=file1]')->attr('value');
print $dom->at('pre')->text;

Output:

foo.c
some code