File Coverage

lib/XML/DOM/Lite/NodeIterator.pm
Criterion Covered Total %
statement 9 73 12.3
branch 0 46 0.0
condition 0 18 0.0
subroutine 3 8 37.5
pod 0 4 0.0
total 12 149 8.0


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