File Coverage

blib/lib/WebService/GData/Serialize/XML.pm
Criterion Covered Total %
statement 67 70 95.7
branch 40 48 83.3
condition 22 32 68.7
subroutine 5 5 100.0
pod 0 1 0.0
total 134 156 85.9


line stmt bran cond sub pod time code
1             package WebService::GData::Serialize::XML;
2 9     9   247 use WebService::GData;
  9         17  
  9         64  
3 9     9   50 use base 'WebService::GData';
  9         15  
  9         9142  
4              
5             our $VERSION = 0.01_03;
6              
7              
8             sub encode {
9 45     45 0 82 my ( $this, $owner) = @_;
10              
11 45 50       385 my $tag =
12             $this->namespace_prefix
13             ? $this->namespace_prefix . ':' . $this->node_name
14             : $this->node_name;
15            
16              
17 45   100     580 my $is_root=(($owner||{}) == $this );
18              
19             #the namespace prefix does not need to be specified
20             #because we set the root namespace as being the default one
21 45 100       407 $tag = $this->node_name if ($is_root);
22             #if it is not the root but a children of the same type
23             #don't need to specify the prefix either
24 45 100 100     118 if ($owner && $this->namespace_prefix eq $owner->namespace_prefix ) {
25 26         99 $tag = $this->node_name;
26             }
27              
28 45         124 my $xml = qq[<$tag];
29              
30             #add the root as the default namespace
31 45 100       145 $xml .= ' xmlns="' . $this->namespace_uri . '"' if ($is_root);
32              
33            
34 45         61 my @attrs = ();
35            
36             #get all the attributes for this node and serialize them
37 45 100       49 if ( @{ $this->attributes } > 0 ) {
  45         268  
38            
39 18         29 foreach my $attr ( @{ $this->attributes } ) {
  18         43  
40 35         185 my $val = $this->{$attr};
41 35 100       152 if ($val){
42 18         29 $val =_to_html_entities($val);
43 18         40 push @attrs,qq[$attr="$val"];
44              
45              
46             #we have an attribute with a prefix, yt:format...
47             #let's append the meta info about this namespace
48 18 100       64 if(my($prefix)=$attr=~m/(.+?):/){
49              
50 1 50 33     4 if(ref $this->extra_namespaces eq 'HASH' && $this->extra_namespaces->{$prefix}){
51 1 50 33     3 $owner->namespaces->{ 'xmlns:' . $prefix . '="'. $this->extra_namespaces->{$prefix}. '"' } = 1
52             if ($owner && $prefix ne $owner->namespace_prefix );
53             }
54             }
55             }
56             }
57 18 100       201 $xml .= ' ' . join( ' ', @attrs ) if @attrs;
58             }
59              
60 45 100       407 if ( $this->is_parent ) {
61            
62 38 100 66     176 return "" if !@attrs && !$this->{text} && !@{$this->child};
  22   66     145  
63              
64 25         41 my $xmlchild = "";
65            
66             #append the text first
67 25 100       75 $xmlchild .= $this->{text} if $this->{text};
68            
69             #serialize all the children
70 25         26 foreach my $child (@{$this->child}) {
  25         169  
71 46         63 my $serialized="";
72 46 100       392 if($child->isa('WebService::GData::Collection')) {
73 14         44 $serialized .= encode($_,$owner) for(@$child);
74 14         26 $xmlchild .= $serialized;
75             }
76             else {
77 32         191 $serialized = encode($child,$owner);
78 32         63 $xmlchild .= $serialized;
79             }
80            
81             #we append the namespace prefix and uri to the root
82 46 100 100     132 __add_namespace_uri($child,$owner) if $owner && length($serialized);
83            
84             }
85            
86 25 100 66     208 return "" if !@attrs && !$this->{text} && !length($xmlchild);
      66        
87            
88 24 100       220 if($is_root) {
89             #gather all the namespaces
90 3         5 my @namespaces = keys %{$owner->namespaces};
  3         10  
91 3 100       26 $xml .= " " . join( " ", @namespaces ) if ( @namespaces > 0 );
92             }
93            
94             #close the root tag
95 24         64 $xml .= '>';
96            
97             #append the children and close the container
98 24         69 $xml .= $xmlchild . qq[];
99             }
100             else {
101             #need to output tags with no attributes working as a flag:
102             #so only if they have attributes but none of them are set and there is no text
103             #we can return early
104 7 100 66     11 return "" if @{ $this->attributes } > 0 && !@attrs && !$this->{text};
  7   66     25  
105 5         16 $xml .= '/>';
106             }
107 29         159 return $xml;
108             }
109              
110             sub __add_namespace_uri {
111 14     14   21 my ($child,$owner) = @_;
112            
113 14         45 my $namespaces= $owner->namespaces;
114            
115             #Node
116 14         66 my $namespace_prefix = $child->namespace_prefix;
117 14         96 my $uri = $child->namespace_uri;
118              
119             #Collection is an array of identic nodes, so look for the first node only
120 14 100       74 if ( $child->isa('WebService::GData::Collection') ) {
121 4         12 my $node = $child->[0];
122 4 50       16 return if !ref $node;
123 4         103 $namespace_prefix = $node->namespace_prefix;
124 4         14 $uri = $node->namespace_uri;
125             }
126             #if this child is an Entity, look for the root
127 14 50       88 if ( $child->isa('WebService::GData::Node::AbstractEntity') ) {
128 0         0 my $node = $child->_entity;
129 0         0 $namespace_prefix = $node->namespace_prefix;
130 0         0 $uri = $node->namespace_uri;
131             }
132              
133 14 0       42 $namespaces->{ 'xmlns'. ( $namespace_prefix ? ':' . $namespace_prefix : "" ) . '="'. $uri. '"' } = 1
    50          
134             if ( $namespace_prefix ne $owner->namespace_prefix );
135            
136             }
137             my %entitymap = (
138             '&'=> '&',
139             '>'=> '>',
140             '<'=> '<',
141             '"'=> '"',
142             "'"=> '''
143             );
144              
145             my $char = '['.join('',(keys %entitymap)).']';
146              
147             sub _to_html_entities {
148 18     18   20 my $val = shift;
149 18         105 $val=~s/($char)/$entitymap{$1}/ge;
  2         7  
150 18         31 return $val;
151             }
152              
153              
154              
155             "The earth is blue like an orange.";
156              
157             __END__