| 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 | XML::NamespaceSupport::_get_ns_details | 
| 142 | 1 | 1 | 346µs | 756µs | XML::NamespaceSupport::process_element_name | 
| 142 | 1 | 1 | 335µs | 335µs | XML::NamespaceSupport::push_context | 
| 142 | 1 | 1 | 171µs | 171µs | XML::NamespaceSupport::pop_context | 
| 56 | 1 | 1 | 145µs | 322µs | XML::NamespaceSupport::process_attribute_name | 
| 8 | 1 | 1 | 49µs | 49µs | XML::NamespaceSupport::declare_prefix | 
| 2 | 1 | 1 | 16µs | 16µs | XML::NamespaceSupport::new | 
| 1 | 1 | 1 | 11µs | 22µs | XML::NamespaceSupport::BEGIN@8 | 
| 1 | 1 | 1 | 10µs | 202µs | XML::NamespaceSupport::BEGIN@9 | 
| 1 | 1 | 1 | 10µs | 23µs | XML::NamespaceSupport::BEGIN@99 | 
| 1 | 1 | 1 | 7µs | 27µs | XML::NamespaceSupport::BEGIN@15 | 
| 1 | 1 | 1 | 7µs | 38µs | XML::NamespaceSupport::BEGIN@18 | 
| 1 | 1 | 1 | 6µs | 23µs | XML::NamespaceSupport::BEGIN@110 | 
| 1 | 1 | 1 | 6µs | 28µs | XML::NamespaceSupport::BEGIN@10 | 
| 1 | 1 | 1 | 6µs | 25µs | XML::NamespaceSupport::BEGIN@11 | 
| 1 | 1 | 1 | 5µs | 24µs | XML::NamespaceSupport::BEGIN@12 | 
| 1 | 1 | 1 | 5µs | 24µs | XML::NamespaceSupport::BEGIN@14 | 
| 1 | 1 | 1 | 5µs | 23µs | XML::NamespaceSupport::BEGIN@13 | 
| 1 | 1 | 1 | 5µs | 23µs | XML::NamespaceSupport::BEGIN@16 | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::declare_prefixes | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::get_declared_prefixes | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::get_prefix | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::get_prefixes | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::get_uri | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::parse_jclark_notation | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::process_name | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::reset | 
| 0 | 0 | 0 | 0s | 0s | XML::NamespaceSupport::undeclare_prefix | 
| 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 |