File Coverage

blib/lib/HTTP/OAI/SAX/Driver.pm
Criterion Covered Total %
statement 78 79 98.7
branch 17 20 85.0
condition n/a
subroutine 12 12 100.0
pod 4 8 50.0
total 111 119 93.2


line stmt bran cond sub pod time code
1             package HTTP::OAI::SAX::Driver;
2              
3 11     11   75 use XML::LibXML;
  11         23  
  11         146  
4 11     11   1535 use base XML::SAX::Base;
  11         24  
  11         863  
5 11     11   63 use XML::NamespaceSupport;
  11         19  
  11         257  
6              
7 11     11   55 use strict;
  11         24  
  11         9467  
8              
9             our $VERSION = '4.12';
10              
11             =pod
12              
13             =head1 NAME
14              
15             HTTP::OAI::SAXHandler - SAX2 utility filter
16              
17             =head1 DESCRIPTION
18              
19             This module provides utility methods for SAX2, including collapsing multiple "characters" events into a single event.
20              
21             This module exports methods for generating SAX2 events with Namespace support. This *isn't* a fully-fledged SAX2 generator!
22              
23             =over 4
24              
25             =item $h = HTTP::OAI::SAXHandler->new()
26              
27             Class constructor.
28              
29             =cut
30              
31             sub new
32             {
33 4     4 1 51 my( $class, %self ) = @_;
34              
35 4         24 $self{ns} = XML::NamespaceSupport->new;
36              
37 4         133 my $self = $class->SUPER::new( %self );
38              
39 4         174 return $self;
40             }
41              
42             sub generate
43             {
44 50     50 0 411 my( $self, $node ) = @_;
45              
46 50         113 my $nodeType = $node->nodeType;
47              
48 50 50       138 if( $nodeType == XML_DOCUMENT_NODE )
    100          
    100          
    50          
49             {
50 0         0 $self->generate( $node->documentElement );
51             }
52             elsif( $nodeType == XML_DOCUMENT_FRAG_NODE )
53             {
54 3         15 $self->generate( $_ ) for $node->childNodes;
55             }
56             elsif( $nodeType == XML_ELEMENT_NODE )
57             {
58             $self->start_element( $node->nodeName, map {
59 27         118 $_->nodeName => $_->nodeValue
  12         143  
60             } $node->attributes
61             );
62 27         1676 $self->generate( $_ ) for $node->childNodes;
63 27         534 $self->end_element( $node->nodeName );
64             }
65             elsif( $nodeType == XML_TEXT_NODE )
66             {
67 20         93 $self->characters( { Data => $node->nodeValue } );
68             }
69             }
70              
71             sub start_oai_pmh
72             {
73 4     4 0 8 my( $self ) = @_;
74              
75 4         26 $self->start_document;
76 4         271 $self->xml_decl({'Version'=>'1.0','Encoding'=>'UTF-8'});
77 4         164 $self->characters({'Data'=>"\n"});
78 4         110 $self->start_prefix_mapping({
79             Prefix => "",
80             NamespaceURI => HTTP::OAI::OAI_NS(),
81             });
82 4         185 $self->start_prefix_mapping({
83             Prefix => "xsi",
84             NamespaceURI => "http://www.w3.org/2001/XMLSchema-instance",
85             });
86             }
87              
88             sub end_oai_pmh
89             {
90 4     4 0 10 my( $self ) = @_;
91              
92 4         38 $self->end_prefix_mapping({
93             Prefix => "",
94             NamespaceURI => HTTP::OAI::OAI_NS(),
95             });
96 4         180 $self->end_prefix_mapping({
97             Prefix => "xsi",
98             NamespaceURI => "http://www.w3.org/2001/XMLSchema-instance",
99             });
100 4         164 $self->end_document;
101             }
102              
103             sub data_element {
104 22     22 0 108 my( $self, $Name, $value, @attr ) = @_;
105              
106 22         47 $self->start_element( $Name, @attr );
107 22         1159 $self->characters( {Data => $value} );
108 22         522 $self->end_element( $Name );
109             }
110              
111             sub start_prefix_mapping
112             {
113 20     20 1 35 my( $self, $hash ) = @_;
114              
115 20         55 $self->{ns}->declare_prefix( $hash->{Prefix}, $hash->{NamespaceURI} );
116              
117 20         474 $self->SUPER::start_prefix_mapping( $hash );
118             }
119              
120             sub start_element
121             {
122 58     58 1 243 my( $self, $Name, @attr ) = @_;
123              
124 58         136 $self->{ns}->push_context;
125              
126 58         495 my %attr;
127 58         155 while(my( $key, $value ) = splice(@attr,0,2))
128             {
129 21 50       38 next if !defined $value;
130 21         28 my( $NamespaceURI, $Prefix, $LocalName );
131 21 100       129 if( $key =~ /^xmlns:(.+)$/ )
    100          
    100          
132             {
133 8         31 $self->start_prefix_mapping( {Prefix => $1, NamespaceURI => $value} );
134 8         255 $NamespaceURI = "http://www.w3.org/2000/xmlns/";
135 8         14 $Prefix = "xmlns";
136 8         16 $LocalName = $1;
137             }
138             elsif( $key eq "xmlns" )
139             {
140 4         14 $self->start_prefix_mapping( {Prefix => '', NamespaceURI => $value} );
141 4         102 $NamespaceURI = '';
142 4         6 $Prefix = '';
143 4         8 $LocalName = $key;
144             }
145             elsif( $key =~ /^(.+):(.+)$/ )
146             {
147 7         26 $NamespaceURI = $self->{ns}->get_uri( $1 );
148 7         80 $Prefix = $1;
149 7         13 $LocalName = $2;
150             }
151             else
152             {
153 2         7 $NamespaceURI = '';
154 2         5 $Prefix = '';
155 2         2 $LocalName = $key;
156             }
157 21         149 $attr{"{$NamespaceURI}$LocalName"} = {
158             NamespaceURI => $NamespaceURI,
159             Prefix => $Prefix,
160             LocalName => $LocalName,
161             Name => $key,
162             Value => $value,
163             };
164             }
165              
166 58         154 my ($Prefix,$LocalName) = split /:/, $Name;
167              
168 58 100       104 unless(defined($LocalName)) {
169 39         47 $LocalName = $Prefix;
170 39         57 $Prefix = '';
171             }
172              
173 58         116 my $NamespaceURI = $self->{ns}->get_uri( $Prefix );
174              
175 58         528 $self->SUPER::start_element({
176             'NamespaceURI'=>$NamespaceURI,
177             'Name'=>$Name,
178             'Prefix'=>$Prefix,
179             'LocalName'=>$LocalName,
180             'Attributes'=>\%attr
181             });
182             }
183              
184             sub end_element
185             {
186 58     58 1 251 my( $self, $Name ) = @_;
187              
188 58         139 my ($Prefix,$LocalName) = split /:/, $Name;
189              
190 58 100       112 unless(defined($LocalName)) {
191 39         48 $LocalName = $Prefix;
192 39         47 $Prefix = '';
193             }
194              
195 58         129 my $NamespaceURI = $self->{ns}->get_uri( $Prefix );
196              
197 58         539 $self->SUPER::end_element({
198             'NamespaceURI'=>$NamespaceURI,
199             'Name'=>$Name,
200             'Prefix'=>$Prefix,
201             'LocalName'=>$LocalName,
202             });
203              
204 58         1818 $self->{ns}->pop_context;
205             }
206              
207             1;
208              
209             __END__