File Coverage

lib/URL/Transform/SAX/Filter.pm
Criterion Covered Total %
statement 36 37 97.3
branch 5 8 62.5
condition n/a
subroutine 8 9 88.8
pod 3 3 100.0
total 52 57 91.2


line stmt bran cond sub pod time code
1             package URL::Transform::SAX::Filter;
2              
3             =head1 NAME
4              
5             URL::Transform::SAX::Filter - SAX filter to execute url transformation function when an attribute with url is found
6              
7             =head1 SYNOPSIS
8              
9             my $writer = XML::SAX::Writer->new( Output => sub {
10             my $type = shift;
11             $output_function->(@_);
12             } );
13             my $filter = URL::Transform::SAX::Filter->new(
14             Handler => $writer,
15             transform_function => sub { return join('|', @_) },
16             );
17            
18             my $sax_parser = XML::SAX::ParserFactory->parser(
19             'Handler' => $filter,
20             );
21            
22             $sax_parser->parse_file('test.html');
23              
24             =head1 DESCRIPTION
25              
26             This filter examines every start tag for a presence of tags and their
27             attributes which may hold link attributes. (SEE L)
28              
29             For each of them the 'transform_function' is triggered which can
30             modify the url. This function receives following arguments:
31              
32             $self->{'transform_function'}->(
33             'tag_name' => 'img',
34             'attribute_name' => 'src',
35             'url' => 'http://search.cpan.org/s/img/cpan_banner.png',
36             );
37              
38             =cut
39              
40 1     1   8 use warnings;
  1         2  
  1         38  
41 1     1   41 use strict;
  1         2  
  1         102  
42              
43             our $VERSION = '0.01';
44              
45 1     1   6 use URL::Transform ();
  1         2  
  1         16  
46 1     1   5 use List::Util 'first';
  1         2  
  1         113  
47 1     1   6 use Carp::Clan 'croak';
  1         1  
  1         19  
48              
49             # Construct a hash of tag names that may have links.
50             my $_link_tags = URL::Transform::link_tags();
51              
52 1     1   199 use base 'XML::SAX::Base';
  1         2  
  1         399  
53              
54             =head1 METHODS
55              
56              
57             =head2 new()
58              
59             Object constructor.
60              
61             Requires the 'transform_function' as the argument.
62              
63             =cut
64              
65             sub new {
66 1     1 1 2 my $class = shift;
67 1         3 my %args = @_;
68            
69 1 50       6 my $transform_function = delete $args{'transform_function'}
70             or croak 'pass "transform_function" os an argument';
71            
72 1         8 my $self = $class->SUPER::new(%args);
73            
74 1         54 $self->{'transform_function'} = $transform_function;
75            
76 1         5 return $self;
77             }
78              
79              
80             =head2 start_element()
81              
82             This function handles the 'transform_function' triggering with a proper
83             arguments.
84              
85             =cut
86              
87             sub start_element {
88 10     10 1 7203 my $self = shift;
89 10         12 my $data = shift;
90              
91 10         14 my $attr = $data->{Attributes};
92 10         19 my $tag_name = lc $data->{'LocalName'};
93              
94             # if the tag belongs to the list of tags that can have a link
95 10 100       38 if (my $link_tag = $_link_tags->{$tag_name}) {
96             # loop through it's attributes
97 8         25 foreach my $ns_attribute_name (keys %$attr) {
98             # extract the attribute name and it's namespace
99 4 50       38 die 'unknown formated attribute name "'.$ns_attribute_name.'"'
100             if not $ns_attribute_name =~ m/^{([^}]*)}(.+)$/;
101 4         8 my $attribute_ns = $1; #we don't use it for the moment
102 4         7 my $attribute_name = $2;
103            
104             # if the attribute is link attribute then execute transform function
105 4 50       16 if ($link_tag->{$attribute_name}) {
106 4         21 $attr->{$ns_attribute_name}->{'Value'} =
107             $self->{'transform_function'}->(
108             'tag_name' => $tag_name,
109             'attribute_name' => $attribute_name,
110             'url' => $attr->{$ns_attribute_name}->{'Value'},
111             );
112             }
113             }
114             }
115              
116 10         130 return $self->SUPER::start_element($data);
117             }
118              
119              
120             =head2 xml_decl
121              
122             Just ignoring xml declaration. Otherwise we'll end-up with
123             C<< >> added to all documents.
124              
125             =cut
126              
127             sub xml_decl {
128 0     0 1   return;
129            
130             }
131              
132              
133             1;
134              
135              
136             __END__