File Coverage

blib/lib/HTML/Similarity.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package HTML::Similarity;
2              
3 1     1   816 use strict;
  1         2  
  1         37  
4 1     1   6 use warnings;
  1         2  
  1         33  
5 1     1   1059 use Data::Dumper;
  1         7112  
  1         81  
6              
7 1     1   1126 use HTML::DOM;
  1         1670095  
  1         72  
8 1     1   393 use Algorithm::LCS;
  0            
  0            
9              
10             sub new {
11             my $class = shift;
12             bless {
13             dom_x => new HTML::DOM,
14             dom_y => new HTML::DOM,
15             lcs => Algorithm::LCS->new,
16             } => $class;
17             }
18              
19             sub _serialize_tree {
20             my $self = shift;
21             my $node = shift;
22              
23             return unless $node->can('tagName');
24              
25             my @serialization;
26              
27             push @serialization, $node->tagName;
28             for my $d ($node->childNodes) {
29             push @serialization, $self->_serialize_tree($d);
30             }
31             return @serialization;
32             }
33              
34             sub calculate_similarity {
35             my $self = shift;
36             my $x = shift || return 0;
37             my $y = shift || return 0;
38              
39             my $dom_x = $self->{dom_x};
40             my $dom_y = $self->{dom_y};
41              
42             $dom_x->open();
43             $dom_x->write($x);
44             $dom_x->close;
45              
46             $dom_y->open();
47             $dom_y->write($y);
48             $dom_y->close;
49              
50             my @seq_x = $self->_serialize_tree($dom_x->documentElement);
51             my @seq_y = $self->_serialize_tree($dom_y->documentElement);
52              
53             my @lcs = $self->{lcs}->LCS(\@seq_x, \@seq_y);
54             return 2 * (scalar @lcs) / (scalar(@seq_x) + scalar(@seq_y));
55             }
56              
57             1;
58             __END__