Subject: | NodeIterator in XML-DOM-Lite Does Not Iterate Properly (nextNode, previousNode) |
The NodeIterator in XML-DOM-Lite does not seem to iterate properly. I
wrote a small program to exercise the NodeIterator, and I walked through
the source code. I identified a potential bug. In lines 48 and 99 of the
NodeIterator.pm, this line:
if ($self->filter->{whatToShow} & (1 << ($self->{currentNode}->nodeType
- 1))) {
should be changed to:
if ($self->{whatToShow} & (1 << ($self->{currentNode}->nodeType - 1))) {
Before the fix, the code would produce this:
perl -I\cygwin\home\rumali\XML-DOM-Lite-0.15\lib testbad.pl
Forwards:
Backwards:
After the "fix":
perl -I\cygwin\home\rumali\XML-DOM-Lite-0.15\lib testbad.pl
Forwards:
Node 1 => page
Node 2 => para
Node 3 => para
Node 4 => para
Node 5 => para
Backwards:
Node 1 => para
Node 2 => para
Node 3 => para
Node 4 => para
Please let me know if there are any questions.
Subject: | testbad.pl |
# testbad.pl
#
# This is a small test program to exercise the NodeIterator
#
# Rick Umali
use XML::DOM::Lite qw(Parser NodeIterator);
use XML::DOM::Lite::Constants qw(:all);
my $xmlstr = q{
<page foo="bar">
<para id="thing1">para thing</para>
<para id="thing2">para thing</para>
<para id="thing3">para thing</para>
<para id="thing4">para thing</para>
</page>
};
my $parser = Parser->new( );
my $doc = $parser->parse( $xmlstr );
my $node_iter = NodeIterator->new($doc->documentElement, SHOW_ELEMENT, {
acceptNode => sub {
my $n = shift;
if ($n->tagName eq "page" || $n->tagName eq "para") {
return FILTER_ACCEPT;
} else {
return FILTER_SKIP;
}
}
}
);
print "Forwards:\n";
my $count = 0;
while (my $node = $node_iter->nextNode) {
$count++;
print "Node $count => " . $node->tagName . "\n";
}
print "Backwards:\n";
$count = 0;
while ($node = $node_iter->previousNode) {
$count++;
print "Node $count => " . $node->tagName . "\n";
}