File Coverage

blib/lib/XML/Filter/Normalize.pm
Criterion Covered Total %
statement 83 83 100.0
branch 18 18 100.0
condition 15 15 100.0
subroutine 15 15 100.0
pod 10 10 100.0
total 141 141 100.0


line stmt bran cond sub pod time code
1             # @(#) $Id: Normalize.pm 1022 2005-10-21 20:42:33Z dom $
2              
3             package XML::Filter::Normalize;
4              
5 2     2   31016 use warnings;
  2         6  
  2         74  
6 2     2   13 use strict;
  2         5  
  2         71  
7              
8 2     2   1898 use XML::NamespaceSupport;
  2         5863  
  2         60  
9 2     2   1963 use XML::SAX::Exception;
  2         4153  
  2         91  
10              
11             our $VERSION = '0.01';
12              
13 2     2   16 use base qw( XML::SAX::Base );
  2         4  
  2         2800  
14              
15             #---------------------------------------------------------------------
16             # Create a new exception class.
17             #---------------------------------------------------------------------
18              
19             @XML::Filter::Normalize::Exception::ISA = qw( XML::SAX::Exception );
20              
21             #---------------------------------------------------------------------
22             # SAX Handlers
23             #---------------------------------------------------------------------
24              
25             sub start_document {
26 1     1 1 1179 my $self = shift;
27 1         6 $self->nsup( XML::NamespaceSupport->new() );
28 1         4 $self->nsup->push_context();
29 1         25 return $self->SUPER::start_document( @_ );
30             }
31              
32             sub end_document {
33 1     1 1 34 my $self = shift;
34 1         4 $self->nsup( undef );
35 1         10 return $self->SUPER::end_document( @_ );
36             }
37              
38             sub start_prefix_mapping {
39 1     1 1 54 my $self = shift;
40 1         3 my ( $data ) = @_;
41 1         4 $self->nsup->declare_prefix( $data->{ Prefix }, $data->{ NamespaceURI } );
42 1         36 return $self->SUPER::start_prefix_mapping( $data );
43             }
44              
45             sub end_prefix_mapping {
46 1     1 1 42 my $self = shift;
47 1         3 my ( $data ) = @_;
48 1         3 $self->nsup->undeclare_prefix( $data->{ Prefix } );
49 1         16 return $self->SUPER::end_prefix_mapping( $data );
50             }
51              
52             sub start_element {
53 1     1 1 53 my $self = shift;
54 1         3 my ( $data ) = @_;
55 1         6 $self->nsup->push_context();
56 1         21 $self->correct_element_data( $self->nsup(), $data );
57 1         13 return $self->SUPER::start_element( $data );
58             }
59              
60             sub end_element {
61 1     1 1 53 my $self = shift;
62 1         3 my ( $data ) = @_;
63 1         3 $self->correct_element_data( $self->nsup(), $data );
64 1         4 $self->nsup->pop_context();
65 1         26 return $self->SUPER::end_element( $data );
66             }
67              
68             #---------------------------------------------------------------------
69             # Internals
70             #---------------------------------------------------------------------
71              
72             sub nsup {
73 9     9 1 34 my $self = shift;
74 9 100       30 $self->{ nsup } = $_[0] if @_;
75 9         47 return $self->{ nsup };
76             }
77              
78             sub correct_element_data {
79 17     17 1 14802 my $self = shift;
80 17         30 my ( $nsup, $data ) = @_;
81              
82 17         39 my ( $uri, $prefix, $lname, $name ) =
83             $self->extract_name_tuple( $nsup, $data );
84              
85 17 100       48 if ( !$lname ) {
86 1         5 $self->whinge('No LocalName found');
87             }
88              
89 16         25 $data->{ NamespaceURI } = $uri;
90 16         28 $data->{ Prefix } = $prefix;
91 16         23 $data->{ LocalName } = $lname;
92 16         20 $data->{ Name } = $name;
93              
94 16         23 my %attr;
95 16         19 foreach my $v ( values %{ $data->{ Attributes } } ) {
  16         66  
96 4         11 my ( $uri, $prefix, $lname, $name ) =
97             $self->extract_name_tuple( $nsup, $v );
98 4         11 $v->{ NamespaceURI } = $uri;
99 4         7 $v->{ Prefix } = $prefix;
100 4         7 $v->{ LocalName } = $lname;
101 4         7 $v->{ Name } = $name;
102 4         8 my $k = "{$uri}$lname";
103 4         16 $attr{ $k } = $v;
104             }
105             # Ensure that all attributes are in the correct key.
106 16         54 $data->{ Attributes } = \%attr;
107              
108             # XXX Should fix up namespace declarations too.
109              
110 16         58 return $data;
111             }
112              
113             sub extract_name_tuple {
114 21     21 1 27 my $self = shift;
115 21         30 my ( $nsup, $data ) = @_;
116 21         62 my ( $uri, $prefix, $lname, $name ) =
117             @$data{ qw( NamespaceURI Prefix LocalName Name ) };
118              
119             # Take a missing prefix from the name if it's there and looks like
120             # we are using a prefix.
121 21 100 100     108 if ( !$prefix && $name && $name =~ m/:/ ) {
      100        
122 3         13 $prefix = ( split /:/, $name, 2 )[0];
123             }
124              
125             # If we don't have a localname, try to take it from name.
126 21 100 100     70 if ( !$lname && $name ) {
127 2 100       8 if ( $name =~ m/:/ ) {
128 1         5 $lname = ( split /:/, $name, 2 )[1];
129             }
130             else {
131 1         3 $lname = $name;
132             }
133             }
134              
135             # If we don't have an NS URI, try to work it out from the prefix.
136             # NB: We can't detect anything in the default namespace if it's
137             # missing it's URI here.
138 21 100 100     67 if ( !$uri && $prefix ) {
139 4         16 $uri = $nsup->get_uri( $prefix );
140             }
141              
142             # If we still have no prefix, but we do have a namespace URI, look
143             # it up.
144 21 100 100     102 if ( !$prefix && $uri ) {
145 3         13 $prefix = $nsup->get_prefix( $uri );
146 3 100       57 $prefix = '' if !defined $prefix;
147             }
148              
149             # Force name to be what we know it should be.
150 21 100       57 $name = $prefix ? $prefix . ':' . $lname : $lname;
151 21         80 return $uri, $prefix, $lname, $name;
152             }
153              
154             sub whinge {
155 1     1 1 3 my $self = shift;
156 1         3 my ( $msg ) = @_;
157              
158 1         18 XML::Filter::Normalize::Exception->throw( Message => $msg );
159             }
160              
161             1;
162             __END__