Filename | /usr/share/perl5/XML/NamespaceSupport.pm |
Statements | Executed 3651 statements in 3.54ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
198 | 2 | 1 | 588µs | 588µs | _get_ns_details | XML::NamespaceSupport::
142 | 1 | 1 | 346µs | 756µs | process_element_name | XML::NamespaceSupport::
142 | 1 | 1 | 335µs | 335µs | push_context | XML::NamespaceSupport::
142 | 1 | 1 | 171µs | 171µs | pop_context | XML::NamespaceSupport::
56 | 1 | 1 | 145µs | 322µs | process_attribute_name | XML::NamespaceSupport::
8 | 1 | 1 | 49µs | 49µs | declare_prefix | XML::NamespaceSupport::
2 | 1 | 1 | 16µs | 16µs | new | XML::NamespaceSupport::
1 | 1 | 1 | 11µs | 22µs | BEGIN@8 | XML::NamespaceSupport::
1 | 1 | 1 | 10µs | 202µs | BEGIN@9 | XML::NamespaceSupport::
1 | 1 | 1 | 10µs | 23µs | BEGIN@99 | XML::NamespaceSupport::
1 | 1 | 1 | 7µs | 27µs | BEGIN@15 | XML::NamespaceSupport::
1 | 1 | 1 | 7µs | 38µs | BEGIN@18 | XML::NamespaceSupport::
1 | 1 | 1 | 6µs | 23µs | BEGIN@110 | XML::NamespaceSupport::
1 | 1 | 1 | 6µs | 28µs | BEGIN@10 | XML::NamespaceSupport::
1 | 1 | 1 | 6µs | 25µs | BEGIN@11 | XML::NamespaceSupport::
1 | 1 | 1 | 5µs | 24µs | BEGIN@12 | XML::NamespaceSupport::
1 | 1 | 1 | 5µs | 24µs | BEGIN@14 | XML::NamespaceSupport::
1 | 1 | 1 | 5µs | 23µs | BEGIN@13 | XML::NamespaceSupport::
1 | 1 | 1 | 5µs | 23µs | BEGIN@16 | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | declare_prefixes | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | get_declared_prefixes | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | get_prefix | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | get_prefixes | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | get_uri | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | parse_jclark_notation | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | process_name | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | reset | XML::NamespaceSupport::
0 | 0 | 0 | 0s | 0s | undeclare_prefix | XML::NamespaceSupport::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | |||||
2 | ### | ||||
3 | # XML::NamespaceSupport - a simple generic namespace processor | ||||
4 | # Robin Berjon <robin@knowscape.com> | ||||
5 | ### | ||||
6 | |||||
7 | package XML::NamespaceSupport; | ||||
8 | 2 | 24µs | 2 | 34µs | # spent 22µs (11+12) within XML::NamespaceSupport::BEGIN@8 which was called:
# once (11µs+12µs) by XML::SAX::Expat::BEGIN@10 at line 8 # spent 22µs making 1 call to XML::NamespaceSupport::BEGIN@8
# spent 12µs making 1 call to strict::import |
9 | 2 | 29µs | 2 | 394µs | # spent 202µs (10+192) within XML::NamespaceSupport::BEGIN@9 which was called:
# once (10µs+192µs) by XML::SAX::Expat::BEGIN@10 at line 9 # spent 202µs making 1 call to XML::NamespaceSupport::BEGIN@9
# spent 192µs making 1 call to constant::import |
10 | 2 | 22µs | 2 | 51µs | # spent 28µs (6+23) within XML::NamespaceSupport::BEGIN@10 which was called:
# once (6µs+23µs) by XML::SAX::Expat::BEGIN@10 at line 10 # spent 28µs making 1 call to XML::NamespaceSupport::BEGIN@10
# spent 23µs making 1 call to constant::import |
11 | 2 | 21µs | 2 | 44µs | # spent 25µs (6+19) within XML::NamespaceSupport::BEGIN@11 which was called:
# once (6µs+19µs) by XML::SAX::Expat::BEGIN@10 at line 11 # spent 25µs making 1 call to XML::NamespaceSupport::BEGIN@11
# spent 19µs making 1 call to constant::import |
12 | 2 | 20µs | 2 | 43µs | # spent 24µs (5+19) within XML::NamespaceSupport::BEGIN@12 which was called:
# once (5µs+19µs) by XML::SAX::Expat::BEGIN@10 at line 12 # spent 24µs making 1 call to XML::NamespaceSupport::BEGIN@12
# spent 19µs making 1 call to constant::import |
13 | 2 | 20µs | 2 | 42µs | # spent 23µs (5+18) within XML::NamespaceSupport::BEGIN@13 which was called:
# once (5µs+18µs) by XML::SAX::Expat::BEGIN@10 at line 13 # spent 23µs making 1 call to XML::NamespaceSupport::BEGIN@13
# spent 18µs making 1 call to constant::import |
14 | 2 | 20µs | 2 | 43µs | # spent 24µs (5+19) within XML::NamespaceSupport::BEGIN@14 which was called:
# once (5µs+19µs) by XML::SAX::Expat::BEGIN@10 at line 14 # spent 24µs making 1 call to XML::NamespaceSupport::BEGIN@14
# spent 19µs making 1 call to constant::import |
15 | 2 | 20µs | 2 | 47µs | # spent 27µs (7+20) within XML::NamespaceSupport::BEGIN@15 which was called:
# once (7µs+20µs) by XML::SAX::Expat::BEGIN@10 at line 15 # spent 27µs making 1 call to XML::NamespaceSupport::BEGIN@15
# spent 20µs making 1 call to constant::import |
16 | 2 | 22µs | 2 | 41µs | # spent 23µs (5+18) within XML::NamespaceSupport::BEGIN@16 which was called:
# once (5µs+18µs) by XML::SAX::Expat::BEGIN@10 at line 16 # spent 23µs making 1 call to XML::NamespaceSupport::BEGIN@16
# spent 18µs making 1 call to constant::import |
17 | |||||
18 | 2 | 292µs | 2 | 69µs | # spent 38µs (7+31) within XML::NamespaceSupport::BEGIN@18 which was called:
# once (7µs+31µs) by XML::SAX::Expat::BEGIN@10 at line 18 # spent 38µs making 1 call to XML::NamespaceSupport::BEGIN@18
# spent 31µs making 1 call to vars::import |
19 | 1 | 400ns | $VERSION = '1.11'; | ||
20 | 1 | 200ns | $NS_XMLNS = 'http://www.w3.org/2000/xmlns/'; | ||
21 | 1 | 100ns | $NS_XML = 'http://www.w3.org/XML/1998/namespace'; | ||
22 | |||||
23 | |||||
24 | # add the ns stuff that baud wants based on Java's xml-writer | ||||
25 | |||||
26 | |||||
27 | #-------------------------------------------------------------------# | ||||
28 | # constructor | ||||
29 | #-------------------------------------------------------------------# | ||||
30 | # spent 16µs within XML::NamespaceSupport::new which was called 2 times, avg 8µs/call:
# 2 times (16µs+0s) by XML::SAX::Expat::_create_parser at line 123 of XML/SAX/Expat.pm, avg 8µs/call | ||||
31 | 2 | 1µs | my $class = ref($_[0]) ? ref(shift) : shift; | ||
32 | 2 | 400ns | my $options = shift; | ||
33 | 2 | 6µs | my $self = [ | ||
34 | 1, # FATALS | ||||
35 | [[ # NSMAP | ||||
36 | undef, # DEFAULT | ||||
37 | { xml => $NS_XML }, # PREFIX_MAP | ||||
38 | undef, # DECLARATIONS | ||||
39 | ]], | ||||
40 | 'aaa', # UNKNOWN_PREF | ||||
41 | 0, # AUTO_PREFIX | ||||
42 | 1, # XML_11 | ||||
43 | ]; | ||||
44 | 2 | 3µs | $self->[NSMAP]->[0]->[PREFIX_MAP]->{xmlns} = $NS_XMLNS if $options->{xmlns}; | ||
45 | 2 | 700ns | $self->[FATALS] = $options->{fatal_errors} if defined $options->{fatal_errors}; | ||
46 | 2 | 800ns | $self->[AUTO_PREFIX] = $options->{auto_prefix} if defined $options->{auto_prefix}; | ||
47 | 2 | 500ns | $self->[XMLNS_11] = $options->{xmlns_11} if defined $options->{xmlns_11}; | ||
48 | 2 | 6µs | return bless $self, $class; | ||
49 | } | ||||
50 | #-------------------------------------------------------------------# | ||||
51 | |||||
52 | #-------------------------------------------------------------------# | ||||
53 | # reset() - return to the original state (for reuse) | ||||
54 | #-------------------------------------------------------------------# | ||||
55 | sub reset { | ||||
56 | my $self = shift; | ||||
57 | $#{$self->[NSMAP]} = 0; | ||||
58 | } | ||||
59 | #-------------------------------------------------------------------# | ||||
60 | |||||
61 | #-------------------------------------------------------------------# | ||||
62 | # push_context() - add a new empty context to the stack | ||||
63 | #-------------------------------------------------------------------# | ||||
64 | # spent 335µs within XML::NamespaceSupport::push_context which was called 142 times, avg 2µs/call:
# 142 times (335µs+0s) by XML::SAX::Expat::_handle_start at line 184 of XML/SAX/Expat.pm, avg 2µs/call | ||||
65 | 142 | 14µs | my $self = shift; | ||
66 | push @{$self->[NSMAP]}, [ | ||||
67 | $self->[NSMAP]->[-1]->[DEFAULT], | ||||
68 | 142 | 431µs | { %{$self->[NSMAP]->[-1]->[PREFIX_MAP]} }, | ||
69 | [], | ||||
70 | ]; | ||||
71 | } | ||||
72 | #-------------------------------------------------------------------# | ||||
73 | |||||
74 | #-------------------------------------------------------------------# | ||||
75 | # pop_context() - remove the topmost context fromt the stack | ||||
76 | #-------------------------------------------------------------------# | ||||
77 | # spent 171µs within XML::NamespaceSupport::pop_context which was called 142 times, avg 1µs/call:
# 142 times (171µs+0s) by XML::SAX::Expat::_handle_end at line 243 of XML/SAX/Expat.pm, avg 1µs/call | ||||
78 | 142 | 18µs | my $self = shift; | ||
79 | 142 | 43µs | die 'Trying to pop context without push context' unless @{$self->[NSMAP]} > 1; | ||
80 | 142 | 179µs | pop @{$self->[NSMAP]}; | ||
81 | } | ||||
82 | #-------------------------------------------------------------------# | ||||
83 | |||||
84 | #-------------------------------------------------------------------# | ||||
85 | # declare_prefix() - declare a prefix in the current scope | ||||
86 | #-------------------------------------------------------------------# | ||||
87 | # spent 49µs within XML::NamespaceSupport::declare_prefix which was called 8 times, avg 6µs/call:
# 8 times (49µs+0s) by XML::SAX::Expat::_handle_start at line 189 of XML/SAX/Expat.pm, avg 6µs/call | ||||
88 | 8 | 1µs | my $self = shift; | ||
89 | 8 | 1µs | my $prefix = shift; | ||
90 | 8 | 1µs | my $value = shift; | ||
91 | |||||
92 | 8 | 2µs | warn <<' EOWARN' unless defined $prefix or $self->[AUTO_PREFIX]; | ||
93 | Prefix was undefined. | ||||
94 | If you wish to set the default namespace, use the empty string ''. | ||||
95 | If you wish to autogenerate prefixes, set the auto_prefix option | ||||
96 | to a true value. | ||||
97 | EOWARN | ||||
98 | |||||
99 | 2 | 76µs | 2 | 37µs | # spent 23µs (10+14) within XML::NamespaceSupport::BEGIN@99 which was called:
# once (10µs+14µs) by XML::SAX::Expat::BEGIN@10 at line 99 # spent 23µs making 1 call to XML::NamespaceSupport::BEGIN@99
# spent 14µs making 1 call to warnings::unimport |
100 | 8 | 7µs | if ($prefix eq 'xml' and $value ne $NS_XML) { | ||
101 | die "The xml prefix can only be bound to the $NS_XML namespace." | ||||
102 | } | ||||
103 | elsif ($value eq $NS_XML and $prefix ne 'xml') { | ||||
104 | die "the $NS_XML namespace can only be bound to the xml prefix."; | ||||
105 | } | ||||
106 | elsif ($value eq $NS_XML and $prefix eq 'xml') { | ||||
107 | return 1; | ||||
108 | } | ||||
109 | 8 | 9µs | return 0 if index(lc($prefix), 'xml') == 0; | ||
110 | 2 | 1.04ms | 2 | 40µs | # spent 23µs (6+17) within XML::NamespaceSupport::BEGIN@110 which was called:
# once (6µs+17µs) by XML::SAX::Expat::BEGIN@10 at line 110 # spent 23µs making 1 call to XML::NamespaceSupport::BEGIN@110
# spent 17µs making 1 call to warnings::import |
111 | |||||
112 | 8 | 5µs | if (defined $prefix and $prefix eq '') { | ||
113 | $self->[NSMAP]->[-1]->[DEFAULT] = $value; | ||||
114 | } | ||||
115 | else { | ||||
116 | 8 | 1µs | die "Cannot undeclare prefix $prefix" if $value eq '' and not $self->[XMLNS_11]; | ||
117 | 8 | 2µs | if (not defined $prefix and $self->[AUTO_PREFIX]) { | ||
118 | while (1) { | ||||
119 | $prefix = $self->[UNKNOWN_PREF]++; | ||||
120 | last if not exists $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix}; | ||||
121 | } | ||||
122 | } | ||||
123 | elsif (not defined $prefix and not $self->[AUTO_PREFIX]) { | ||||
124 | return 0; | ||||
125 | } | ||||
126 | 8 | 7µs | $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix} = $value; | ||
127 | } | ||||
128 | 8 | 5µs | push @{$self->[NSMAP]->[-1]->[DECLARATIONS]}, $prefix; | ||
129 | 8 | 14µs | return 1; | ||
130 | } | ||||
131 | #-------------------------------------------------------------------# | ||||
132 | |||||
133 | #-------------------------------------------------------------------# | ||||
134 | # declare_prefixes() - declare several prefixes in the current scope | ||||
135 | #-------------------------------------------------------------------# | ||||
136 | sub declare_prefixes { | ||||
137 | my $self = shift; | ||||
138 | my %prefixes = @_; | ||||
139 | while (my ($k,$v) = each %prefixes) { | ||||
140 | $self->declare_prefix($k,$v); | ||||
141 | } | ||||
142 | } | ||||
143 | #-------------------------------------------------------------------# | ||||
144 | |||||
145 | #-------------------------------------------------------------------# | ||||
146 | # undeclare_prefix | ||||
147 | #-------------------------------------------------------------------# | ||||
148 | sub undeclare_prefix { | ||||
149 | my $self = shift; | ||||
150 | my $prefix = shift; | ||||
151 | return unless not defined $prefix or $prefix eq ''; | ||||
152 | return unless exists $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix}; | ||||
153 | |||||
154 | my ( $tfix ) = grep { $_ eq $prefix } @{$self->[NSMAP]->[-1]->[DECLARATIONS]}; | ||||
155 | if ( not defined $tfix ) { | ||||
156 | die "prefix $prefix not declared in this context\n"; | ||||
157 | } | ||||
158 | |||||
159 | @{$self->[NSMAP]->[-1]->[DECLARATIONS]} = grep { $_ ne $prefix } @{$self->[NSMAP]->[-1]->[DECLARATIONS]}; | ||||
160 | delete $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix}; | ||||
161 | } | ||||
162 | #-------------------------------------------------------------------# | ||||
163 | |||||
164 | #-------------------------------------------------------------------# | ||||
165 | # get_prefix() - get a (random) prefix for a given URI | ||||
166 | #-------------------------------------------------------------------# | ||||
167 | sub get_prefix { | ||||
168 | my $self = shift; | ||||
169 | my $uri = shift; | ||||
170 | |||||
171 | # we have to iterate over the whole hash here because if we don't | ||||
172 | # the iterator isn't reset and the next pass will fail | ||||
173 | my $pref; | ||||
174 | while (my ($k, $v) = each %{$self->[NSMAP]->[-1]->[PREFIX_MAP]}) { | ||||
175 | $pref = $k if $v eq $uri; | ||||
176 | } | ||||
177 | return $pref; | ||||
178 | } | ||||
179 | #-------------------------------------------------------------------# | ||||
180 | |||||
181 | #-------------------------------------------------------------------# | ||||
182 | # get_prefixes() - get all the prefixes for a given URI | ||||
183 | #-------------------------------------------------------------------# | ||||
184 | sub get_prefixes { | ||||
185 | my $self = shift; | ||||
186 | my $uri = shift; | ||||
187 | |||||
188 | return keys %{$self->[NSMAP]->[-1]->[PREFIX_MAP]} unless defined $uri; | ||||
189 | return grep { $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$_} eq $uri } keys %{$self->[NSMAP]->[-1]->[PREFIX_MAP]}; | ||||
190 | } | ||||
191 | #-------------------------------------------------------------------# | ||||
192 | |||||
193 | #-------------------------------------------------------------------# | ||||
194 | # get_declared_prefixes() - get all prefixes declared in the last context | ||||
195 | #-------------------------------------------------------------------# | ||||
196 | sub get_declared_prefixes { | ||||
197 | return @{$_[0]->[NSMAP]->[-1]->[DECLARATIONS]}; | ||||
198 | } | ||||
199 | #-------------------------------------------------------------------# | ||||
200 | |||||
201 | #-------------------------------------------------------------------# | ||||
202 | # get_uri() - get an URI given a prefix | ||||
203 | #-------------------------------------------------------------------# | ||||
204 | sub get_uri { | ||||
205 | my $self = shift; | ||||
206 | my $prefix = shift; | ||||
207 | |||||
208 | warn "Prefix must not be undef in get_uri(). The emtpy prefix must be ''" unless defined $prefix; | ||||
209 | |||||
210 | return $self->[NSMAP]->[-1]->[DEFAULT] if $prefix eq ''; | ||||
211 | return $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix} if exists $self->[NSMAP]->[-1]->[PREFIX_MAP]->{$prefix}; | ||||
212 | return undef; | ||||
213 | } | ||||
214 | #-------------------------------------------------------------------# | ||||
215 | |||||
216 | #-------------------------------------------------------------------# | ||||
217 | # process_name() - provide details on a name | ||||
218 | #-------------------------------------------------------------------# | ||||
219 | sub process_name { | ||||
220 | my $self = shift; | ||||
221 | my $qname = shift; | ||||
222 | my $aflag = shift; | ||||
223 | |||||
224 | if ($self->[FATALS]) { | ||||
225 | return( ($self->_get_ns_details($qname, $aflag))[0,2], $qname ); | ||||
226 | } | ||||
227 | else { | ||||
228 | eval { return( ($self->_get_ns_details($qname, $aflag))[0,2], $qname ); } | ||||
229 | } | ||||
230 | } | ||||
231 | #-------------------------------------------------------------------# | ||||
232 | |||||
233 | #-------------------------------------------------------------------# | ||||
234 | # process_element_name() - provide details on a element's name | ||||
235 | #-------------------------------------------------------------------# | ||||
236 | # spent 756µs (346+411) within XML::NamespaceSupport::process_element_name which was called 142 times, avg 5µs/call:
# 142 times (346µs+411µs) by XML::SAX::Expat::_handle_start at line 215 of XML/SAX/Expat.pm, avg 5µs/call | ||||
237 | 142 | 19µs | my $self = shift; | ||
238 | 142 | 17µs | my $qname = shift; | ||
239 | |||||
240 | 142 | 246µs | 142 | 411µs | if ($self->[FATALS]) { # spent 411µs making 142 calls to XML::NamespaceSupport::_get_ns_details, avg 3µs/call |
241 | return $self->_get_ns_details($qname, 0); | ||||
242 | } | ||||
243 | else { | ||||
244 | eval { return $self->_get_ns_details($qname, 0); } | ||||
245 | } | ||||
246 | } | ||||
247 | #-------------------------------------------------------------------# | ||||
248 | |||||
249 | |||||
250 | #-------------------------------------------------------------------# | ||||
251 | # process_attribute_name() - provide details on a attribute's name | ||||
252 | #-------------------------------------------------------------------# | ||||
253 | # spent 322µs (145+177) within XML::NamespaceSupport::process_attribute_name which was called 56 times, avg 6µs/call:
# 56 times (145µs+177µs) by XML::SAX::Expat::_handle_start at line 202 of XML/SAX/Expat.pm, avg 6µs/call | ||||
254 | 56 | 7µs | my $self = shift; | ||
255 | 56 | 10µs | my $qname = shift; | ||
256 | |||||
257 | 56 | 100µs | 56 | 177µs | if ($self->[FATALS]) { # spent 177µs making 56 calls to XML::NamespaceSupport::_get_ns_details, avg 3µs/call |
258 | return $self->_get_ns_details($qname, 1); | ||||
259 | } | ||||
260 | else { | ||||
261 | eval { return $self->_get_ns_details($qname, 1); } | ||||
262 | } | ||||
263 | } | ||||
264 | #-------------------------------------------------------------------# | ||||
265 | |||||
266 | |||||
267 | #-------------------------------------------------------------------# | ||||
268 | # ($ns, $prefix, $lname) = $self->_get_ns_details($qname, $f_attr) | ||||
269 | # returns ns, prefix, and lname for a given attribute name | ||||
270 | # >> the $f_attr flag, if set to one, will work for an attribute | ||||
271 | #-------------------------------------------------------------------# | ||||
272 | # spent 588µs within XML::NamespaceSupport::_get_ns_details which was called 198 times, avg 3µs/call:
# 142 times (411µs+0s) by XML::NamespaceSupport::process_element_name at line 240, avg 3µs/call
# 56 times (177µs+0s) by XML::NamespaceSupport::process_attribute_name at line 257, avg 3µs/call | ||||
273 | 198 | 20µs | my $self = shift; | ||
274 | 198 | 23µs | my $qname = shift; | ||
275 | 198 | 17µs | my $aflag = shift; | ||
276 | |||||
277 | 198 | 12µs | my ($ns, $prefix, $lname); | ||
278 | 198 | 195µs | (my ($tmp_prefix, $tmp_lname) = split /:/, $qname, 3) | ||
279 | < 3 or die "Invalid QName: $qname"; | ||||
280 | |||||
281 | # no prefix | ||||
282 | 198 | 37µs | my $cur_map = $self->[NSMAP]->[-1]; | ||
283 | 198 | 51µs | if (not defined($tmp_lname)) { | ||
284 | 182 | 18µs | $prefix = undef; | ||
285 | 182 | 21µs | $lname = $qname; | ||
286 | # attr don't have a default namespace | ||||
287 | 182 | 33µs | $ns = ($aflag) ? undef : $cur_map->[DEFAULT]; | ||
288 | } | ||||
289 | |||||
290 | # prefix | ||||
291 | else { | ||||
292 | 16 | 7µs | if (exists $cur_map->[PREFIX_MAP]->{$tmp_prefix}) { | ||
293 | 16 | 2µs | $prefix = $tmp_prefix; | ||
294 | 16 | 2µs | $lname = $tmp_lname; | ||
295 | 16 | 5µs | $ns = $cur_map->[PREFIX_MAP]->{$prefix} | ||
296 | } | ||||
297 | else { # no ns -> lname == name, all rest undef | ||||
298 | die "Undeclared prefix: $tmp_prefix"; | ||||
299 | } | ||||
300 | } | ||||
301 | |||||
302 | 198 | 331µs | return ($ns, $prefix, $lname); | ||
303 | } | ||||
304 | #-------------------------------------------------------------------# | ||||
305 | |||||
306 | #-------------------------------------------------------------------# | ||||
307 | # parse_jclark_notation() - parse the Clarkian notation | ||||
308 | #-------------------------------------------------------------------# | ||||
309 | sub parse_jclark_notation { | ||||
310 | shift; | ||||
311 | my $jc = shift; | ||||
312 | $jc =~ m/^\{(.*)\}([^}]+)$/; | ||||
313 | return $1, $2; | ||||
314 | } | ||||
315 | #-------------------------------------------------------------------# | ||||
316 | |||||
317 | |||||
318 | #-------------------------------------------------------------------# | ||||
319 | # Java names mapping | ||||
320 | #-------------------------------------------------------------------# | ||||
321 | 1 | 1µs | *XML::NamespaceSupport::pushContext = \&push_context; | ||
322 | 1 | 300ns | *XML::NamespaceSupport::popContext = \&pop_context; | ||
323 | 1 | 100ns | *XML::NamespaceSupport::declarePrefix = \&declare_prefix; | ||
324 | 1 | 100ns | *XML::NamespaceSupport::declarePrefixes = \&declare_prefixes; | ||
325 | 1 | 200ns | *XML::NamespaceSupport::getPrefix = \&get_prefix; | ||
326 | 1 | 200ns | *XML::NamespaceSupport::getPrefixes = \&get_prefixes; | ||
327 | 1 | 200ns | *XML::NamespaceSupport::getDeclaredPrefixes = \&get_declared_prefixes; | ||
328 | 1 | 100ns | *XML::NamespaceSupport::getURI = \&get_uri; | ||
329 | 1 | 200ns | *XML::NamespaceSupport::processName = \&process_name; | ||
330 | 1 | 100ns | *XML::NamespaceSupport::processElementName = \&process_element_name; | ||
331 | 1 | 100ns | *XML::NamespaceSupport::processAttributeName = \&process_attribute_name; | ||
332 | 1 | 200ns | *XML::NamespaceSupport::parseJClarkNotation = \&parse_jclark_notation; | ||
333 | 1 | 100ns | *XML::NamespaceSupport::undeclarePrefix = \&undeclare_prefix; | ||
334 | #-------------------------------------------------------------------# | ||||
335 | |||||
336 | |||||
337 | 1 | 6µs | 1; | ||
338 | #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# | ||||
339 | #`,`, Documentation `,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,`,# | ||||
340 | #```````````````````````````````````````````````````````````````````# | ||||
341 | |||||
342 | =pod | ||||
343 | |||||
344 | =head1 NAME | ||||
345 | |||||
346 | XML::NamespaceSupport - a simple generic namespace support class | ||||
347 | |||||
348 | =head1 SYNOPSIS | ||||
349 | |||||
350 | use XML::NamespaceSupport; | ||||
351 | my $nsup = XML::NamespaceSupport->new; | ||||
352 | |||||
353 | # add a new empty context | ||||
354 | $nsup->push_context; | ||||
355 | # declare a few prefixes | ||||
356 | $nsup->declare_prefix($prefix1, $uri1); | ||||
357 | $nsup->declare_prefix($prefix2, $uri2); | ||||
358 | # the same shorter | ||||
359 | $nsup->declare_prefixes($prefix1 => $uri1, $prefix2 => $uri2); | ||||
360 | |||||
361 | # get a single prefix for a URI (randomly) | ||||
362 | $prefix = $nsup->get_prefix($uri); | ||||
363 | # get all prefixes for a URI (probably better) | ||||
364 | @prefixes = $nsup->get_prefixes($uri); | ||||
365 | # get all prefixes in scope | ||||
366 | @prefixes = $nsup->get_prefixes(); | ||||
367 | # get all prefixes that were declared for the current scope | ||||
368 | @prefixes = $nsup->get_declared_prefixes; | ||||
369 | # get a URI for a given prefix | ||||
370 | $uri = $nsup->get_uri($prefix); | ||||
371 | |||||
372 | # get info on a qname (java-ish way, it's a bit weird) | ||||
373 | ($ns_uri, $local_name, $qname) = $nsup->process_name($qname, $is_attr); | ||||
374 | # the same, more perlish | ||||
375 | ($ns_uri, $prefix, $local_name) = $nsup->process_element_name($qname); | ||||
376 | ($ns_uri, $prefix, $local_name) = $nsup->process_attribute_name($qname); | ||||
377 | |||||
378 | # remove the current context | ||||
379 | $nsup->pop_context; | ||||
380 | |||||
381 | # reset the object for reuse in another document | ||||
382 | $nsup->reset; | ||||
383 | |||||
384 | # a simple helper to process Clarkian Notation | ||||
385 | my ($ns, $lname) = $nsup->parse_jclark_notation('{http://foo}bar'); | ||||
386 | # or (given that it doesn't care about the object | ||||
387 | my ($ns, $lname) = XML::NamespaceSupport->parse_jclark_notation('{http://foo}bar'); | ||||
388 | |||||
389 | |||||
390 | =head1 DESCRIPTION | ||||
391 | |||||
392 | This module offers a simple to process namespaced XML names (unames) | ||||
393 | from within any application that may need them. It also helps maintain | ||||
394 | a prefix to namespace URI map, and provides a number of basic checks. | ||||
395 | |||||
396 | The model for this module is SAX2's NamespaceSupport class, readable at | ||||
397 | http://www.megginson.com/SAX/Java/javadoc/org/xml/sax/helpers/NamespaceSupport.html. | ||||
398 | It adds a few perlisations where we thought it appropriate. | ||||
399 | |||||
400 | =head1 METHODS | ||||
401 | |||||
402 | =over 4 | ||||
403 | |||||
404 | =item * XML::NamespaceSupport->new(\%options) | ||||
405 | |||||
406 | A simple constructor. | ||||
407 | |||||
408 | The options are C<xmlns>, C<fatal_errors>, and C<auto_prefix> | ||||
409 | |||||
410 | If C<xmlns> is turned on (it is off by default) the mapping from the | ||||
411 | xmlns prefix to the URI defined for it in DOM level 2 is added to the | ||||
412 | list of predefined mappings (which normally only contains the xml | ||||
413 | prefix mapping). | ||||
414 | |||||
415 | If C<fatal_errors> is turned off (it is on by default) a number of | ||||
416 | validity errors will simply be flagged as failures, instead of | ||||
417 | die()ing. | ||||
418 | |||||
419 | If C<auto_prefix> is turned on (it is off by default) when one | ||||
420 | provides a prefix of C<undef> to C<declare_prefix> it will generate a | ||||
421 | random prefix mapped to that namespace. Otherwise an undef prefix will | ||||
422 | trigger a warning (you should probably know what you're doing if you | ||||
423 | turn this option on). | ||||
424 | |||||
425 | If C<xmlns_11> us turned off, it becomes illegal to undeclare namespace | ||||
426 | prefixes. It is on by default. This behaviour is compliant with Namespaces | ||||
427 | in XML 1.1, turning it off reverts you to version 1.0. | ||||
428 | |||||
429 | =item * $nsup->push_context | ||||
430 | |||||
431 | Adds a new empty context to the stack. You can then populate it with | ||||
432 | new prefixes defined at this level. | ||||
433 | |||||
434 | =item * $nsup->pop_context | ||||
435 | |||||
436 | Removes the topmost context in the stack and reverts to the previous | ||||
437 | one. It will die() if you try to pop more than you have pushed. | ||||
438 | |||||
439 | =item * $nsup->declare_prefix($prefix, $uri) | ||||
440 | |||||
441 | Declares a mapping of $prefix to $uri, at the current level. | ||||
442 | |||||
443 | Note that with C<auto_prefix> turned on, if you declare a prefix | ||||
444 | mapping in which $prefix is undef(), you will get an automatic prefix | ||||
445 | selected for you. If it is off you will get a warning. | ||||
446 | |||||
447 | This is useful when you deal with code that hasn't kept prefixes around | ||||
448 | and need to reserialize the nodes. It also means that if you want to | ||||
449 | set the default namespace (ie with an empty prefix) you must use the | ||||
450 | empty string instead of undef. This behaviour is consistent with the | ||||
451 | SAX 2.0 specification. | ||||
452 | |||||
453 | =item * $nsup->declare_prefixes(%prefixes2uris) | ||||
454 | |||||
455 | Declares a mapping of several prefixes to URIs, at the current level. | ||||
456 | |||||
457 | =item * $nsup->get_prefix($uri) | ||||
458 | |||||
459 | Returns a prefix given an URI. Note that as several prefixes may be | ||||
460 | mapped to the same URI, it returns an arbitrary one. It'll return | ||||
461 | undef on failure. | ||||
462 | |||||
463 | =item * $nsup->get_prefixes($uri) | ||||
464 | |||||
465 | Returns an array of prefixes given an URI. It'll return all the | ||||
466 | prefixes if the uri is undef. | ||||
467 | |||||
468 | =item * $nsup->get_declared_prefixes | ||||
469 | |||||
470 | Returns an array of all the prefixes that have been declared within | ||||
471 | this context, ie those that were declared on the last element, not | ||||
472 | those that were declared above and are simply in scope. | ||||
473 | |||||
474 | =item * $nsup->get_uri($prefix) | ||||
475 | |||||
476 | Returns a URI for a given prefix. Returns undef on failure. | ||||
477 | |||||
478 | =item * $nsup->process_name($qname, $is_attr) | ||||
479 | |||||
480 | Given a qualified name and a boolean indicating whether this is an | ||||
481 | attribute or another type of name (those are differently affected by | ||||
482 | default namespaces), it returns a namespace URI, local name, qualified | ||||
483 | name tuple. I know that that is a rather abnormal list to return, but | ||||
484 | it is so for compatibility with the Java spec. See below for more | ||||
485 | Perlish alternatives. | ||||
486 | |||||
487 | If the prefix is not declared, or if the name is not valid, it'll | ||||
488 | either die or return undef depending on the current setting of | ||||
489 | C<fatal_errors>. | ||||
490 | |||||
491 | =item * $nsup->undeclare_prefix($prefix); | ||||
492 | |||||
493 | Removes a namespace prefix from the current context. This function may | ||||
494 | be used in SAX's end_prefix_mapping when there is fear that a namespace | ||||
495 | declaration might be available outside their scope (which shouldn't | ||||
496 | normally happen, but you never know ;). This may be needed in order to | ||||
497 | properly support Namespace 1.1. | ||||
498 | |||||
499 | =item * $nsup->process_element_name($qname) | ||||
500 | |||||
501 | Given a qualified name, it returns a namespace URI, prefix, and local | ||||
502 | name tuple. This method applies to element names. | ||||
503 | |||||
504 | If the prefix is not declared, or if the name is not valid, it'll | ||||
505 | either die or return undef depending on the current setting of | ||||
506 | C<fatal_errors>. | ||||
507 | |||||
508 | =item * $nsup->process_attribute_name($qname) | ||||
509 | |||||
510 | Given a qualified name, it returns a namespace URI, prefix, and local | ||||
511 | name tuple. This method applies to attribute names. | ||||
512 | |||||
513 | If the prefix is not declared, or if the name is not valid, it'll | ||||
514 | either die or return undef depending on the current setting of | ||||
515 | C<fatal_errors>. | ||||
516 | |||||
517 | =item * $nsup->reset | ||||
518 | |||||
519 | Resets the object so that it can be reused on another document. | ||||
520 | |||||
521 | =back | ||||
522 | |||||
523 | All methods of the interface have an alias that is the name used in | ||||
524 | the original Java specification. You can use either name | ||||
525 | interchangeably. Here is the mapping: | ||||
526 | |||||
527 | Java name Perl name | ||||
528 | --------------------------------------------------- | ||||
529 | pushContext push_context | ||||
530 | popContext pop_context | ||||
531 | declarePrefix declare_prefix | ||||
532 | declarePrefixes declare_prefixes | ||||
533 | getPrefix get_prefix | ||||
534 | getPrefixes get_prefixes | ||||
535 | getDeclaredPrefixes get_declared_prefixes | ||||
536 | getURI get_uri | ||||
537 | processName process_name | ||||
538 | processElementName process_element_name | ||||
539 | processAttributeName process_attribute_name | ||||
540 | parseJClarkNotation parse_jclark_notation | ||||
541 | undeclarePrefix undeclare_prefix | ||||
542 | |||||
543 | =head1 VARIABLES | ||||
544 | |||||
545 | Two global variables are made available to you. They used to be constants but | ||||
546 | simple scalars are easier to use in a number of contexts. They are not | ||||
547 | exported but can easily be accessed from any package, or copied into it. | ||||
548 | |||||
549 | =over 4 | ||||
550 | |||||
551 | =item * C<$NS_XMLNS> | ||||
552 | |||||
553 | The namespace for xmlns prefixes, http://www.w3.org/2000/xmlns/. | ||||
554 | |||||
555 | =item * C<$NS_XML> | ||||
556 | |||||
557 | The namespace for xml prefixes, http://www.w3.org/XML/1998/namespace. | ||||
558 | |||||
559 | =back | ||||
560 | |||||
561 | =head1 TODO | ||||
562 | |||||
563 | - add more tests | ||||
564 | - optimise here and there | ||||
565 | |||||
566 | =head1 AUTHOR | ||||
567 | |||||
568 | Robin Berjon, robin@knowscape.com, with lots of it having been done | ||||
569 | by Duncan Cameron, and a number of suggestions from the perl-xml | ||||
570 | list. | ||||
571 | |||||
572 | =head1 COPYRIGHT | ||||
573 | |||||
574 | Copyright (c) 2001-2005 Robin Berjon. All rights reserved. This program is | ||||
575 | free software; you can redistribute it and/or modify it under the same terms | ||||
576 | as Perl itself. | ||||
577 | |||||
578 | =head1 SEE ALSO | ||||
579 | |||||
580 | XML::Parser::PerlSAX | ||||
581 | |||||
582 | =cut | ||||
583 |