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   79 use XML::LibXML;
  11         26  
  11         104  
4 11     11   1697 use base XML::SAX::Base;
  11         24  
  11         1065  
5 11     11   72 use XML::NamespaceSupport;
  11         34  
  11         254  
6              
7 11     11   70 use strict;
  11         29  
  11         10421  
8              
9             our $VERSION = '4.11';
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 65 my( $class, %self ) = @_;
34              
35 4         32 $self{ns} = XML::NamespaceSupport->new;
36              
37 4         111 my $self = $class->SUPER::new( %self );
38              
39 4         234 return $self;
40             }
41              
42             sub generate
43             {
44 50     50 0 449 my( $self, $node ) = @_;
45              
46 50         138 my $nodeType = $node->nodeType;
47              
48 50 50       129 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         19 $self->generate( $_ ) for $node->childNodes;
55             }
56             elsif( $nodeType == XML_ELEMENT_NODE )
57             {
58             $self->start_element( $node->nodeName, map {
59 27         95 $_->nodeName => $_->nodeValue
  12         183  
60             } $node->attributes
61             );
62 27         1703 $self->generate( $_ ) for $node->childNodes;
63 27         562 $self->end_element( $node->nodeName );
64             }
65             elsif( $nodeType == XML_TEXT_NODE )
66             {
67 20         103 $self->characters( { Data => $node->nodeValue } );
68             }
69             }
70              
71             sub start_oai_pmh
72             {
73 4     4 0 13 my( $self ) = @_;
74              
75 4         28 $self->start_document;
76 4         371 $self->xml_decl({'Version'=>'1.0','Encoding'=>'UTF-8'});
77 4         226 $self->characters({'Data'=>"\n"});
78 4         138 $self->start_prefix_mapping({
79             Prefix => "",
80             NamespaceURI => HTTP::OAI::OAI_NS(),
81             });
82 4         201 $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 11 my( $self ) = @_;
91              
92 4         58 $self->end_prefix_mapping({
93             Prefix => "",
94             NamespaceURI => HTTP::OAI::OAI_NS(),
95             });
96 4         203 $self->end_prefix_mapping({
97             Prefix => "xsi",
98             NamespaceURI => "http://www.w3.org/2001/XMLSchema-instance",
99             });
100 4         240 $self->end_document;
101             }
102              
103             sub data_element {
104 22     22 0 134 my( $self, $Name, $value, @attr ) = @_;
105              
106 22         54 $self->start_element( $Name, @attr );
107 22         1422 $self->characters( {Data => $value} );
108 22         576 $self->end_element( $Name );
109             }
110              
111             sub start_prefix_mapping
112             {
113 20     20 1 37 my( $self, $hash ) = @_;
114              
115 20         69 $self->{ns}->declare_prefix( $hash->{Prefix}, $hash->{NamespaceURI} );
116              
117 20         534 $self->SUPER::start_prefix_mapping( $hash );
118             }
119              
120             sub start_element
121             {
122 58     58 1 262 my( $self, $Name, @attr ) = @_;
123              
124 58         140 $self->{ns}->push_context;
125              
126 58         486 my %attr;
127 58         164 while(my( $key, $value ) = splice(@attr,0,2))
128             {
129 21 50       44 next if !defined $value;
130 21         32 my( $NamespaceURI, $Prefix, $LocalName );
131 21 100       136 if( $key =~ /^xmlns:(.+)$/ )
    100          
    100          
132             {
133 8         36 $self->start_prefix_mapping( {Prefix => $1, NamespaceURI => $value} );
134 8         267 $NamespaceURI = "http://www.w3.org/2000/xmlns/";
135 8         11 $Prefix = "xmlns";
136 8         16 $LocalName = $1;
137             }
138             elsif( $key eq "xmlns" )
139             {
140 4         25 $self->start_prefix_mapping( {Prefix => '', NamespaceURI => $value} );
141 4         119 $NamespaceURI = '';
142 4         6 $Prefix = '';
143 4         6 $LocalName = $key;
144             }
145             elsif( $key =~ /^(.+):(.+)$/ )
146             {
147 7         32 $NamespaceURI = $self->{ns}->get_uri( $1 );
148 7         84 $Prefix = $1;
149 7         21 $LocalName = $2;
150             }
151             else
152             {
153 2         5 $NamespaceURI = '';
154 2         11 $Prefix = '';
155 2         5 $LocalName = $key;
156             }
157 21         169 $attr{"{$NamespaceURI}$LocalName"} = {
158             NamespaceURI => $NamespaceURI,
159             Prefix => $Prefix,
160             LocalName => $LocalName,
161             Name => $key,
162             Value => $value,
163             };
164             }
165              
166 58         168 my ($Prefix,$LocalName) = split /:/, $Name;
167              
168 58 100       120 unless(defined($LocalName)) {
169 39         50 $LocalName = $Prefix;
170 39         51 $Prefix = '';
171             }
172              
173 58         127 my $NamespaceURI = $self->{ns}->get_uri( $Prefix );
174              
175 58         608 $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 260 my( $self, $Name ) = @_;
187              
188 58         148 my ($Prefix,$LocalName) = split /:/, $Name;
189              
190 58 100       118 unless(defined($LocalName)) {
191 39         54 $LocalName = $Prefix;
192 39         52 $Prefix = '';
193             }
194              
195 58         113 my $NamespaceURI = $self->{ns}->get_uri( $Prefix );
196              
197 58         569 $self->SUPER::end_element({
198             'NamespaceURI'=>$NamespaceURI,
199             'Name'=>$Name,
200             'Prefix'=>$Prefix,
201             'LocalName'=>$LocalName,
202             });
203              
204 58         1968 $self->{ns}->pop_context;
205             }
206              
207             1;
208              
209             __END__