File Coverage

lib/XML/DOM/Lite/NodeIterator.pm
Criterion Covered Total %
statement 15 79 18.9
branch 0 46 0.0
condition 0 18 0.0
subroutine 5 10 50.0
pod 0 4 0.0
total 20 157 12.7


line stmt bran cond sub pod time code
1             package XML::DOM::Lite::NodeIterator;
2 7     7   40 use warnings;
  7         15  
  7         207  
3 7     7   35 use strict;
  7         13  
  7         142  
4              
5 7     7   29 use XML::DOM::Lite::Constants qw(:all);
  7         9  
  7         1012  
6              
7 7     7   41 use constant BEFORE => -1;
  7         10  
  7         432  
8 7     7   37 use constant AFTER => 1;
  7         12  
  7         4342  
9              
10             sub new {
11 0     0 0   my ($class, $root, $whatToShow, $nodeFilter) = @_;
12 0           my $self = bless {
13             root => $root,
14             whatToShow => $whatToShow
15             }, $class;
16 0 0         unless (defined $nodeFilter) {
17 0     0     $self->filter({ acceptNode => sub { return FILTER_ACCEPT } });
  0            
18             } else {
19 0           $self->filter($nodeFilter);
20             }
21 0           $self->{currentNode} = $root;
22 0           $self->{POSITION} = BEFORE;
23              
24 0           return $self;
25             }
26              
27 0 0   0 0   sub filter { $_[0]->{filter} = $_[1] if $_[1]; $_[0]->{filter} }
  0            
28              
29             sub nextNode {
30 0     0 0   my $self = shift;
31 0           for (;;) {
32 0 0         if ($self->{POSITION} == BEFORE) {
    0          
    0          
    0          
33             # do nothing so we test the currentNode
34             } elsif ($self->{currentNode}->childNodes->length) {
35 0           $self->{currentNode} = $self->{currentNode}->childNodes->[0];
36             } elsif ($self->{currentNode}->nextSibling) {
37 0           $self->{currentNode} = $self->{currentNode}->nextSibling;
38             } elsif ($self->{currentNode}->parentNode) {
39 0           my $p = $self->{currentNode}->parentNode;
40 0   0       while ($p and $p->nextSibling == undef and $p != $self->{root}) {
      0        
41 0           $p = $p->parentNode;
42             }
43 0 0 0       last unless ($p and $p->nextSibling);
44 0           $self->{currentNode} = $p->nextSibling;
45             } else {
46 0           last;
47             }
48 0           $self->{POSITION} = AFTER;
49 0           my $rv;
50 0 0         if ($self->filter->{whatToShow} & (1 << ($self->{currentNode}->nodeType - 1))) {
51 0           $rv = $self->filter->{acceptNode}->($self->{currentNode});
52             } else {
53 0           $rv = FILTER_REJECT;
54             }
55              
56 0 0         if ($rv == FILTER_ACCEPT) {
    0          
    0          
57 0           return $self->{currentNode};
58             }
59             elsif ($rv == FILTER_SKIP) {
60 0 0         if ($self->{currentNode}->nextSibling) {
61 0           $self->{currentNode} = $self->{currentNode}->nextSibling;
62             } else {
63 0           my $p = $self->{currentNode}->parentNode;
64 0   0       while ($p and $p->nextSibling == undef) {
65 0           $p = $p->parentNode;
66             }
67 0 0 0       last unless ($p and $p->nextSibling);
68 0           $self->{currentNode} = $p->nextSibling;
69             }
70 0           next;
71             }
72             elsif ($rv != FILTER_REJECT) {
73 0           die('filter returned unknown value: `'.$rv."'");
74             }
75             }
76 0           return undef;
77             }
78              
79             sub previousNode {
80 0     0 0   my $self = shift;
81 0           for (;;) {
82 0 0 0       if ($self->{POSITION} == AFTER) {
    0          
    0          
83             # do nothing
84             } elsif ($self->{currentNode}->previousSibling) {
85 0           my $p = $self->{currentNode}->previousSibling;
86 0 0         if ($p->childNodes->length) {
87 0           $self->{currentNode} = $p->childNodes->[$p->childNodes->length-1];
88 0           while ($self->{currentNode}->childNodes->length) {
89 0           $self->{currentNode} = $self->{currentNode}->childNodes->[$self->{currentNode}->childNodes->length - 1];
90             }
91             } else {
92 0           $self->{currentNode} = $p;
93             }
94             } elsif ($self->{currentNode}->parentNode and $self->{currentNode}->parentNode != $self->{root}) {
95 0           $self->{currentNode} = $self->{currentNode}->parentNode;
96             } else {
97 0           last;
98             }
99 0           $self->{POSITION} = BEFORE;
100 0           my $rv;
101 0 0         if ($self->filter->{whatToShow} & (1 << ($self->{currentNode}->nodeType - 1))) {
102 0           $rv = $self->filter->{acceptNode}->($self->{currentNode});
103             } else {
104 0           $rv = FILTER_REJECT;
105             }
106              
107 0 0         if ($rv == FILTER_ACCEPT) {
    0          
    0          
108 0           return $self->{currentNode};
109             }
110             elsif ($rv == FILTER_SKIP) {
111 0 0         if ($self->{currentNode}->previousSibling) {
    0          
112 0           $self->{currentNode} = $self->{currentNode}->previousSibling;
113             } elsif ($self->{currentNode}->parentNode) {
114 0           $self->{currentNode} = $self->{currentNode}->parentNode;
115             } else {
116 0           last;
117             }
118 0           next;
119             }
120             elsif ($rv != FILTER_REJECT) {
121 0           die('filter returned unknown value: `'.$rv."'");
122             }
123             }
124 0           return undef;
125             }
126              
127             1;