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