File Coverage

blib/lib/XML/Filter/Digest.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             # XML::Filter::Digest
2             #
3             # Copyright (c) 2000 Michael Koehne
4             #
5             # XML::Filter::Digest is free software. You can use and redistribute
6             # this copy under terms of GNU General Public license.
7              
8 1     1   906 use strict;
  1         2  
  1         44  
9              
10             #------------------------------------------------------------------------------#
11              
12             package XML::Filter::Digest;
13              
14 1     1   1637 use XML::XPath;
  0            
  0            
15             use XML::XPath::Builder;
16             use XML::XPath::Node;
17             use XML::XPath::Node::Element;
18             use XML::Parser::PerlSAX;
19              
20             use vars qw($VERSION @ISA $METHODS $DEBUG);
21              
22             $VERSION="0.06";
23             @ISA = qw( XML::XPath::Builder );
24             $METHODS = {
25             start_document => 1,
26             end_document => 1,
27             start_element => 1,
28             end_element => 1,
29             characters => 1
30             };
31             $DEBUG = 0;
32              
33             sub new {
34             my $proto = shift;
35             my $self = ($#_ == 0) ? { %{ (shift) } } : { @_ };
36             my $class = ref($proto) || $proto;
37              
38             bless $self, $class;
39              
40             die "no Handler defined" unless $self->{'Handler'};
41              
42             return $self;
43             }
44              
45             sub parse {
46             my $self = shift;
47              
48             die "no Source defined" unless $self->{'Source'};
49            
50             my $parser = new XML::Parser::PerlSAX(
51             'Handler' => $self,
52             'Source' => $self->{'Source'}
53             );
54             $parser->parse();
55              
56             return $self;
57             }
58              
59             sub start_document {
60             my $self = shift;
61              
62             $self->{'Methods'} = {};
63             foreach (keys %$METHODS) {
64             $self->{'Methods'}{$_} = 1 if $self->{'Handler'}->can($_);
65             }
66              
67             $self->{'Handler'}->start_document()
68             if $self->{'Methods'}{'start_document'};
69              
70             XML::XPath::Builder::start_document($self);
71             }
72              
73             sub end_document {
74             my $self = shift;
75             my $result;
76              
77             my $xp = XML::XPath->new( context => $self->{DOC_Node} );
78             $self->{'xp'} = $xp;
79             $self->recurse( $self->{'Script'}, $self->{DOC_Node} );
80             $self->{'xp'} = undef;
81             $xp->cleanup();
82              
83             delete $self->{Last};
84             delete $self->{Current};
85              
86             $result = $self->{'Handler'}->end_document()
87             if $self->{'Methods'}{'end_document'};
88             return $result;
89             }
90              
91             sub recurse {
92             my ($self,$script,$root) = @_;
93              
94             print STDERR "script ".$script->{'name'}."=".$script->{'node'}."\n"
95             if $DEBUG;
96              
97             $self->{'Handler'}->start_element( { 'Name' => $script->{'name'} } )
98             if $self->{'Methods'}{'start_element'} && $script->{'name'};
99              
100             foreach my $collect (@{$script->{'_'}}) {
101             print STDERR "collect ".$collect->{'name'}."=".$collect->{'node'}."\n"
102             if $DEBUG;
103             foreach ($self->{'xp'}->findnodes($collect->{'node'},$root)) {
104             if ($#{$collect->{'_'}}>=0) {
105             $self->recurse($collect,$_);
106             } else {
107             $self->{'Handler'}->start_element( { 'Name' => $collect->{'name'} } )
108             if $self->{'Methods'}{'start_element'};
109              
110             # $self->{'Handler'}->characters( { 'Data' => XML::XPath::XMLParser::string_value($_) } )
111             # if $self->{'Methods'}{'characters'};
112              
113             print STDERR "node : ",ref($_),"\n"
114             if $DEBUG;
115              
116             $self->{'Handler'}->characters( { 'Data' => $_->string_value } )
117             if $self->{'Methods'}{'characters'};
118              
119             $self->{'Handler'}->end_element( { 'Name' => $collect->{'name'} } )
120             if $self->{'Methods'}{'end_element'};
121             }
122             }
123             }
124              
125             $self->{'Handler'}->end_element( { 'Name' => $script->{'name'} } )
126             if $self->{'Methods'}{'start_element'} && $script->{'name'};
127             }
128              
129             #------------------------------------------------------------------------------#
130              
131             package XML::Script::Digest;
132              
133             use XML::Parser::PerlSAX;
134              
135             sub new {
136             my $proto = shift;
137             my $self = ($#_ == 0) ? { %{ (shift) } } : { @_ };
138             my $class = ref($proto) || $proto;
139              
140             bless $self, $class;
141              
142             return $self;
143             }
144              
145             sub parse {
146             my $self = shift;
147              
148             die "no Source defined" unless $self->{'Source'};
149              
150             my $parser = new XML::Parser::PerlSAX(
151             'Handler' => $self,
152             'Source' => $self->{'Source'}
153             );
154             $parser->parse;
155              
156             return $self;
157             }
158              
159             sub start_document {
160             my ($self, $element) = @_;
161              
162             $self->{'!'} = [];
163             $self->{'_'} = [];
164             }
165              
166             sub end_document {
167             my ($self, $element) = @_;
168              
169             die "non wellformed".$#{$self->{'!'}} if $#{$self->{'!'}}>=0;
170            
171             delete $self->{'!'};
172             return $self;
173             }
174              
175             sub start_element {
176             my ($self, $element) = @_;
177              
178             if ($element->{Name} eq "collect") {
179             my $name = $element->{Attributes}{'name'};
180             my $node = $element->{Attributes}{'node'};
181              
182             die "collect element requires node attribute" unless $node;
183             # die "collect element requires name attribute" unless $name;
184              
185             my $coll = {};
186              
187             $coll->{'name'}=$name;
188             $coll->{'node'}=$node;
189             $coll->{'_'}=[];
190              
191             push @{$self->{'_'}}, $coll;
192             push @{$self->{'!'}}, $self->{'_'};
193              
194             $self->{'_'} = $coll->{'_'};
195             }
196             if ($element->{Name} eq "digest") {
197             my $name = $element->{Attributes}{'name'};
198             die "digest element requires name attribute" unless $name;
199             $self->{'name'}=$name;
200             }
201             }
202              
203             sub end_element {
204             my ($self, $element) = @_;
205              
206             if ($element->{Name} eq "collect") {
207             $self->{'_'} = pop @{$self->{'!'}};
208             }
209             }
210              
211             1;
212              
213             __END__