File Coverage

blib/lib/XML/LibXML/NodeList.pm
Criterion Covered Total %
statement 99 117 84.6
branch 16 30 53.3
condition 0 6 0.0
subroutine 28 34 82.3
pod 20 25 80.0
total 163 212 76.8


line stmt bran cond sub pod time code
1             # $Id$
2             #
3             # This is free software, you may use it and distribute it under the same terms as
4             # Perl itself.
5             #
6             # Copyright 2001-2003 AxKit.com Ltd., 2002-2006 Christian Glahn, 2006-2009 Petr Pajas
7             #
8             #
9              
10             package XML::LibXML::NodeList;
11              
12 66     66   479 use strict;
  66         140  
  66         2082  
13 66     66   336 use warnings;
  66         133  
  66         1879  
14              
15 66     66   29821 use XML::LibXML::Boolean;
  66         184  
  66         1619  
16 66     66   417 use XML::LibXML::Literal;
  66         144  
  66         1092  
17 66     66   307 use XML::LibXML::Number;
  66         123  
  66         1303  
18              
19 66     66   294 use vars qw($VERSION);
  66         120  
  66         7906  
20             $VERSION = "2.0207"; # VERSION TEMPLATE: DO NOT CHANGE
21              
22             use overload
23             '""' => \&to_literal,
24             'bool' => \&to_boolean,
25             'cmp' => sub {
26 2     2   13 my($aa, $bb, $order) = @_;
27 2 50       8 return ($order ? ("$bb" cmp "$aa") : ("$aa" cmp "$bb"));
28             },
29 66     66   448 ;
  66         191  
  66         816  
30              
31             sub new {
32 97     97 1 2614 my $class = shift;
33 97         939 bless [@_], $class;
34             }
35              
36             sub new_from_ref {
37 16     16 0 54 my ($class,$array_ref,$reuse) = @_;
38 16 50       114 return bless $reuse ? $array_ref : [@$array_ref], $class;
39             }
40              
41             sub pop {
42 23     23 1 64 my $self = CORE::shift;
43 23         234 CORE::pop @$self;
44             }
45              
46             sub push {
47 0     0 1 0 my $self = CORE::shift;
48 0         0 CORE::push @$self, @_;
49             }
50              
51             sub append {
52 0     0 1 0 my $self = CORE::shift;
53 0         0 my ($nodelist) = @_;
54 0         0 CORE::push @$self, $nodelist->get_nodelist;
55             }
56              
57             sub shift {
58 7     7 1 30 my $self = CORE::shift;
59 7         49 CORE::shift @$self;
60             }
61              
62             sub unshift {
63 10     10 1 25 my $self = CORE::shift;
64 10         21 CORE::unshift @$self, @_;
65             }
66              
67             sub prepend {
68 0     0 1 0 my $self = CORE::shift;
69 0         0 my ($nodelist) = @_;
70 0         0 CORE::unshift @$self, $nodelist->get_nodelist;
71             }
72              
73             sub size {
74 24     24 1 1525 my $self = CORE::shift;
75 24         198 scalar @$self;
76             }
77              
78             sub get_node {
79             # uses array index starting at 1, not 0
80             # this is mainly because of XPath.
81 5     5 1 27 my $self = CORE::shift;
82 5         11 my ($pos) = @_;
83 5         159 $self->[$pos - 1];
84             }
85              
86             sub item
87             {
88 1     1 0 3 my ($self, $pos) = @_;
89 1         55 return $self->[$pos];
90             }
91              
92             sub get_nodelist {
93 0     0 1 0 my $self = CORE::shift;
94 0         0 @$self;
95             }
96              
97             sub to_boolean {
98 3     3 0 360 my $self = CORE::shift;
99 3 50       23 return (@$self > 0) ? XML::LibXML::Boolean->True : XML::LibXML::Boolean->False;
100             }
101              
102             # string-value of a nodelist is the string-value of the first node
103             sub string_value {
104 1     1 1 3 my $self = CORE::shift;
105 1 50       7 return '' unless @$self;
106 1         20 return $self->[0]->string_value;
107             }
108              
109             sub to_literal {
110 26     26 1 56 my $self = CORE::shift;
111             return XML::LibXML::Literal->new(
112 26         113 join('', CORE::grep {defined $_} CORE::map { $_->string_value } @$self)
  55         216  
  55         279  
113             );
114             }
115              
116             sub to_literal_delimited {
117 1     1 1 3 my $self = CORE::shift;
118             return XML::LibXML::Literal->new(
119 1         4 join(CORE::shift, CORE::grep {defined $_} CORE::map { $_->string_value } @$self)
  5         15  
  5         20  
120             );
121             }
122              
123             sub to_literal_list {
124 1     1 1 3 my $self = CORE::shift;
125 1         2 my @nodes = CORE::map{ XML::LibXML::Literal->new($_->string_value())->value() } @{$self};
  5         27  
  1         4  
126              
127 1 50       5 if (wantarray) {
128 1         12 return( @nodes );
129             }
130 0         0 return( \@nodes );
131             }
132              
133             sub to_number {
134 0     0 0 0 my $self = CORE::shift;
135 0         0 return XML::LibXML::Number->new(
136             $self->to_literal
137             );
138             }
139              
140             sub iterator {
141 0     0 0 0 warn "this function is obsolete!\nIt was disabled in version 1.54\n";
142 0         0 return undef;
143             }
144              
145             sub map {
146 3     3 1 1800 my $self = CORE::shift;
147 3         19 my $sub = __is_code(CORE::shift);
148 3         4 local $_;
149 3         8 my @results = CORE::map { @{[ $sub->($_) ]} } @$self;
  30         98  
  30         50  
150 3 50       19 return unless defined wantarray;
151 3 100       15 return wantarray ? @results : (ref $self)->new(@results);
152             }
153              
154             sub grep {
155 2     2 1 701 my $self = CORE::shift;
156 2         6 my $sub = __is_code(CORE::shift);
157 2         4 local $_;
158 2         6 my @results = CORE::grep { $sub->($_) } @$self;
  20         52  
159 2 50       20 return unless defined wantarray;
160 2 100       11 return wantarray ? @results : (ref $self)->new(@results);
161             }
162              
163             sub sort {
164 2     2 1 21 my $self = CORE::shift;
165 2         7 my $sub = __is_code(CORE::shift);
166 2         13 my @results = CORE::sort { $sub->($a,$b) } @$self;
  43         152  
167 2 50       21 return wantarray ? @results : (ref $self)->new(@results);
168             }
169              
170             sub foreach {
171 1     1 1 10 my $self = CORE::shift;
172 1         3 my $sub = CORE::shift;
173              
174 1         4 foreach my $item (@$self)
175             {
176 10         17 local $_ = $item;
177 10         17 $sub->($item);
178             }
179              
180 1 50       5 return wantarray ? @$self : $self;
181             }
182              
183             sub reverse {
184 1     1 1 1340 my $self = CORE::shift;
185 1         6 my @results = CORE::reverse @$self;
186 1 50       6 return wantarray ? @results : (ref $self)->new(@results);
187             }
188              
189             sub reduce {
190 2     2 1 1438 my $self = CORE::shift;
191 2         7 my $sub = __is_code(CORE::shift);
192              
193 2         7 my @list = @$self;
194 2 50       8 CORE::unshift @list, $_[0] if @_;
195              
196 2         4 my $a = CORE::shift(@list);
197 2         7 foreach my $b (@list)
198             {
199 20         66 $a = $sub->($a, $b);
200             }
201 2         11 return $a;
202             }
203              
204             sub __is_code {
205 9     9   19 my ($code) = @_;
206              
207 9 50       29 if (ref $code eq 'CODE') {
208 9         19 return $code;
209             }
210              
211             # There are better ways of doing this, but here I've tried to
212             # avoid adding any additional external dependencies.
213             #
214 0 0 0       if (UNIVERSAL::can($code, 'can') # is blessed (sort of)
      0        
215             and overload::Overloaded($code) # is overloaded
216             and overload::Method($code, '&{}')) { # overloads '&{}'
217 0           return $code;
218             }
219              
220             # The other possibility is that $code is a coderef, but is
221             # blessed into a class that doesn't overload '&{}'. In which
222             # case... well, I'm stumped!
223              
224 0           die "Not a subroutine reference\n";
225             }
226              
227             1;
228             __END__