File Coverage

blib/lib/XML/Filter/Hekeln.pm
Criterion Covered Total %
statement 9 131 6.8
branch 0 56 0.0
condition 0 12 0.0
subroutine 3 17 17.6
pod 0 13 0.0
total 12 229 5.2


line stmt bran cond sub pod time code
1             # XML::Filter::Hekeln
2             # (c) 1999 GNU General Public License
3             # Michael Koehne Kraehe@Copyleft.de
4             # ---------------------------------------------------------------------------- #
5              
6             package XML::Filter::Hekeln;
7 1     1   1722 use UNIVERSAL;
  1         14  
  1         5  
8              
9 1     1   29 use strict;
  1         1  
  1         35  
10 1     1   5 use vars qw($VERSION $METHODS);
  1         6  
  1         1712  
11              
12             $VERSION = '0.06';
13             $METHODS = {
14             start_document => 1,
15             end_document => 1,
16             doctype_decl => 1,
17             processing_instruction => 1,
18             start_element => 1,
19             end_element => 1,
20             start_cdata => 1,
21             end_cdata => 1,
22             characters => 1
23             };
24              
25             # ---------------------------------------------------------------------------- #
26              
27             sub new {
28 0     0 0   my $proto = shift;
29 0           my $self = {};
30 0   0       my $class = ref($proto) || $proto;
31 0           bless($self, $class);
32              
33 0 0         my $args = ($#_ == 0) ? { %{ (shift) } } : { @_ };
  0            
34              
35 0           foreach (keys %$args) { $self->{$_}=$args->{$_}; }
  0            
36              
37 0 0 0       $self->{'Action'} = $self->script($self->{'Script'})
38             if $self->{'Script'} && !$self->{'Action'};
39              
40 0 0         $self->{'Action'} = {} unless ref($self->{'Action'}) eq 'HASH';
41 0           $self->{'Methods'} = {};
42 0           $self->{'Stack'} = [];
43              
44 0 0         if ($self->{'Handler'}) {
45 0           foreach (keys %$METHODS) {
46 0 0         $self->{'Methods'}{$_} =
47             $self->{'Handler'}->can($_) ? 2 : 1;
48             }
49             }
50              
51 0           return $self;
52             }
53              
54             sub script {
55 0     0 0   my ($self,$script) = @_;
56 0           my $hash = {};
57 0           my ($key,$val,$str);
58 0           my (@v, $o, $p);
59 0           my $action;
60              
61 0     0     local $SIG{__WARN__} = sub { die $_[0] };
  0            
62              
63 0           foreach (split /\n\n/, $script) {
64 0 0         if ($_ !~ /^#/) {
65 0           ($key,$val) = split /\n/, $_, 2;
66 0 0         if ($key =~ /^[^:]+:[^:]+$/) {
67              
68 0           $str = 'sub {'."\n\t";
69 0           $str .= 'my ($self,$param) = @_;'."\n\t";
70 0           $str .= 'my ($hash) = {};'."\n\t";
71              
72 0           $val =~ s/\~(\w+)\~/\$param->{$1}/g;
73              
74 0           SCRIPT_TO_SUB_SW: foreach (split /\n/, $val) {
75 0           @v = split /\t/, $_;
76 0           $o = shift @v;
77 0           $p = shift @v;
78              
79 0 0         if ($o eq '<') {
80 0           $str .= '$hash->{Name}="'.$p.'"; ';
81 0           $str .= '$self->handle("start_element", $hash);';
82 0           $str .= "\n\t";
83 0           next SCRIPT_TO_SUB_SW;
84             }
85            
86 0 0         if ($o eq '
87 0           $str .= '$hash->{Name}="'.$p.'"; ';
88 0           $str .= '$self->handle("end_element", $hash);';
89 0           $str .= "\n\t";
90 0           next SCRIPT_TO_SUB_SW;
91             }
92            
93 0 0         if ($o eq '') {
94 0           $str .= '$hash->{Data}="'.$p.'"; ';
95 0           $str .= '$self->handle("characters", $hash);';
96 0           $str .= "\n\t";
97 0           next SCRIPT_TO_SUB_SW;
98             }
99            
100 0 0         if ($o eq '!') {
101 0           $str .= $p;
102 0           $str .= "\n\t";
103 0           next SCRIPT_TO_SUB_SW;
104             }
105              
106 0 0         if ($o eq '+') {
107 0           $str .= '$self->{Flag}{'.$p.'}=1;';
108 0           $str .= "\n\t";
109 0           next SCRIPT_TO_SUB_SW;
110             }
111 0 0         if ($o eq '++') {
112 0           $str .= '$self->{Flag}{'.$p.'}=1;';
113 0           $str .= 'unshift @{$self->{Stack}}, "'.$p.'";';
114 0           $str .= "\n\t";
115 0           next SCRIPT_TO_SUB_SW;
116             }
117 0 0         if ($o eq '-') {
118 0           $str .= '$self->{Flag}{'.$p.'}=0;';
119 0           $str .= "\n\t";
120 0           next SCRIPT_TO_SUB_SW;
121             }
122 0 0         if ($o eq '--') {
123 0           $str .= '$self->{Flag}{'.$p.'}=0;';
124 0           $str .= 'shift @{$self->{Stack}} if $self->{Stack}[0] eq "'.$p.'";';
125 0           $str .= "\n\t";
126 0           next SCRIPT_TO_SUB_SW;
127             }
128 0 0         if ($o eq '?{') {
129 0           $str .= 'if ($self->{Flag}{'.$p.'}) {';
130 0           $str .= "\n\t";
131 0           next SCRIPT_TO_SUB_SW;
132             }
133 0 0         if ($o eq '?}') {
134 0           $str .= '}';
135 0           $str .= "\n\t";
136 0           next SCRIPT_TO_SUB_SW;
137             }
138             }
139 0           $str.= '}';
140 0 0         print STDERR '$hash->{'.$key.'}=eval "'.$str.'";'."\n\n"
141             if $self->{'Debug'};
142 0           $action = eval $str;
143 0 0         if ($@) {
144 0           print STDERR "Error: $key: "; die $@
  0            
145             }
146 0           $hash->{$key}=$action;
147             }
148             }
149             }
150 0           return $hash;
151             }
152              
153 0     0 0   sub start_document { my ($self, $param) = @_; $self->style('start_document',$param); }
  0            
154 0     0 0   sub end_document { my ($self, $param) = @_; $self->style('end_document',$param); }
  0            
155 0     0 0   sub doctype_decl { my ($self, $param) = @_; $self->style('doctype_decl',$param); }
  0            
156 0     0 0   sub processing_instruction { my ($self, $param) = @_; $self->style('processing_instruction',$param); }
  0            
157 0     0 0   sub start_element { my ($self, $param) = @_; $self->style('start_element',$param); }
  0            
158 0     0 0   sub end_element { my ($self, $param) = @_; $self->style('end_element',$param); }
  0            
159 0     0 0   sub start_cdata { my ($self, $param) = @_; $self->style('start_cdata',$param); }
  0            
160 0     0 0   sub end_cdata { my ($self, $param) = @_; $self->style('end_cdata',$param); }
  0            
161 0     0 0   sub characters { my ($self, $param) = @_; $self->style('characters',$param); }
  0            
162              
163             sub style {
164 0     0 0   my ($self,$event,$param) = @_;
165              
166 0 0         return unless $param;
167 0 0         return unless $event;
168 0 0         return unless $METHODS->{$event};
169              
170 0           my $target = "*";
171 0 0         $target = $param->{'Name'} if $param->{'Name'};
172 0 0         $target = $param->{'Target'} if $param->{'Target'};
173 0 0 0       $target = $self->{Stack}[0] if ( $event eq 'characters' or
      0        
174             $event eq 'start_cdata' or
175             $event eq 'end_cdata' ) and
176             $self->{Flag}{$self->{Stack}[0]};
177              
178 0           my $action = $self->{'Action'}{$event.':'.$target};
179 0 0         return undef unless $action;
180              
181 0           my $hash = $param;
182 0 0         $hash = $param->{'Attributes'} if $event eq 'start_element';
183              
184 0           return &$action($self,$hash);
185             }
186              
187             sub handle {
188 0     0 0   my ($self,$event,$param) = @_;
189              
190 0 0         return $self->{'Handler'}->$event($param)
191             if ($self->{'Methods'}{$event}>1);
192 0           return undef;
193             }
194              
195             # ---------------------------------------------------------------------------- #
196              
197             1;
198             __END__