File Coverage

blib/lib/XML/Filter/NSNormalise.pm
Criterion Covered Total %
statement 75 75 100.0
branch 21 22 95.4
condition 5 9 55.5
subroutine 10 10 100.0
pod 5 5 100.0
total 116 121 95.8


line stmt bran cond sub pod time code
1             # $Id: NSNormalise.pm,v 1.5 2002/10/11 02:01:43 grantm Exp $
2              
3             package XML::Filter::NSNormalise;
4              
5 2     2   224411 use strict;
  2         5  
  2         75  
6 2     2   11 use warnings;
  2         5  
  2         60  
7 2     2   11 use Carp;
  2         8  
  2         169  
8              
9 2     2   1571 use XML::SAX::Base;
  2         37918  
  2         68  
10              
11 2     2   22 use vars qw($VERSION @ISA);
  2         4  
  2         1915  
12              
13             $VERSION = '0.04';
14              
15             @ISA = qw(XML::SAX::Base);
16              
17              
18             ##############################################################################
19             # Constructor: new()
20             #
21             # Validate mappings and delegate to base class constructor.
22             #
23              
24             sub new {
25 9     9 1 777406 my $class = shift;
26 9         34 my %args = @_;
27              
28 9 50 66     75 if(!$args{Map} or !ref($args{Map}) or !%{$args{Map}}) {
  8   33     48  
29 1         125 croak "No 'Map' option in call to XML::Filter::NSNormalise->new()";
30             }
31 8         17 my %revmap;
32 8         15 while(my($uri, $prefix) = each %{$args{Map}} ) {
  19         75  
33 12 100 66     57 if($revmap{$prefix} and $revmap{$prefix} ne $uri) {
34 1         263 croak "Multiple URIs mapped to prefix '$prefix'"
35             }
36 11         34 $revmap{$prefix} = $uri;
37             }
38            
39 7         66 $class->SUPER::new(@_, ReverseMap => \%revmap);
40             }
41              
42              
43             ##############################################################################
44             # Method: start_prefix_mapping()
45             # Method: end_prefix_mapping()
46             #
47             # Intercept any namespace prefix events for which we have a mapping and
48             # normalise the 'Prefix'.
49             #
50              
51             sub start_prefix_mapping {
52 13     13 1 20012 my $self = shift;
53 13         26 my $event = shift;
54              
55 13 100       54 if($self->{Map}->{$event->{NamespaceURI}}) {
56 8         33 $event = { %$event };
57 8         34 $event->{Prefix} = $self->{Map}->{$event->{NamespaceURI}};
58             }
59 13         66 $self->SUPER::start_prefix_mapping($event);
60             }
61              
62             sub end_prefix_mapping {
63 11     11 1 863 my $self = shift;
64 11         18 my $event = shift;
65              
66 11 100       41 if($self->{Map}->{$event->{NamespaceURI}}) {
67 7         19 $event = { %$event };
68 7         24 $event->{Prefix} = $self->{Map}->{$event->{NamespaceURI}};
69             }
70 11         42 $self->SUPER::end_prefix_mapping($event);
71             }
72              
73              
74             ##############################################################################
75             # Method: start_element()
76             # Method: end_element()
77             #
78             # - Fix the 'Prefix' and 'Name' data for elements in a mapped namespace
79             # - Fix the 'LocalName' and 'Name' data for namespace declaration attributes
80             # - Fix the 'Prefix' and 'Name' data for attributes in a mapped namespace
81             #
82              
83             sub start_element {
84 18     18 1 21897 my $self = shift;
85 18         26 my $event = shift;
86              
87 18         89 $event = { %$event }; # make a (shallow) copy of the event data
88 18         37 my %new_attr;
89              
90 18 100       76 if($self->{Map}->{$event->{NamespaceURI}}) {
91 10         33 $event->{Prefix} = $self->{Map}->{$event->{NamespaceURI}};
92 10         33 $event->{Name} = "$event->{Prefix}:$event->{LocalName}";
93             }
94 18         24 foreach my $key (keys %{$event->{Attributes}}) {
  18         59  
95 17         36 my $attr = $event->{Attributes}->{$key};
96              
97 17 100       54 if($attr->{Prefix} eq 'xmlns') {
    100          
98 8 100       27 if($self->{ReverseMap}->{$attr->{LocalName}}) {
99 2 100       10 if($attr->{Value} ne $self->{ReverseMap}->{$attr->{LocalName}}) {
100 1         30 die "Cannot map '$self->{ReverseMap}->{$attr->{LocalName}}' to " .
101             "'$attr->{LocalName}' - prefix already occurs in document";
102             }
103             }
104 7 100       27 if($self->{Map}->{$attr->{Value}}) {
105 5         23 $attr = { %$attr };
106 5         17 $attr->{LocalName} = $self->{Map}->{$attr->{Value}};
107 5         12 $attr->{Name} = "xmlns:$attr->{LocalName}";
108 5         21 $new_attr{"{http://www.w3.org/2000/xmlns/}$attr->{LocalName}"} = $attr;
109             }
110             else {
111 2         23 $new_attr{$key} = $attr;
112             }
113             }
114             elsif($self->{Map}->{$attr->{NamespaceURI}}) {
115 2         10 $attr = { %$attr };
116 2         6 $attr->{Prefix} = $self->{Map}->{$attr->{NamespaceURI}};
117 2         5 $attr->{Name} = "$attr->{Prefix}:$attr->{LocalName}";
118 2         6 my $new_key = "{$attr->{NamespaceURI}}$attr->{LocalName}";
119 2         6 $new_attr{$new_key} = $attr;
120 2         10 delete($event->{Attributes}->{$key});
121             }
122             else {
123 7         23 $new_attr{$key} = $attr;
124             }
125              
126             }
127 17         37 $event->{Attributes} = \%new_attr;
128 17         1052 $self->SUPER::start_element($event);
129             }
130              
131             sub end_element {
132 17     17 1 5987 my $self = shift;
133 17         20 my $event = shift;
134              
135 17 100       64 if($self->{Map}->{$event->{NamespaceURI}}) {
136 10         63 $event = { %$event };
137 10         34 $event->{Prefix} = $self->{Map}->{$event->{NamespaceURI}};
138 10         22 $event->{Name} = "$event->{Prefix}:$event->{LocalName}";
139             }
140 17         63 $self->SUPER::end_element($event);
141             }
142              
143              
144             1;
145             __END__