diff -Naur XML-XPath-1.13/MANIFEST XML-XPath-1.13.01/MANIFEST --- XML-XPath-1.13/MANIFEST 2001-06-12 22:56:08.000000000 +0200 +++ XML-XPath-1.13.01/MANIFEST 2005-03-02 10:08:42.000000000 +0100 @@ -59,5 +59,7 @@ t/remove.t t/insert.t t/stress.t +t/test_comp_bug.t examples/test.xml examples/xpath +META.yml Module meta-data (added by MakeMaker) diff -Naur XML-XPath-1.13/META.yml XML-XPath-1.13.01/META.yml --- XML-XPath-1.13/META.yml 1970-01-01 01:00:00.000000000 +0100 +++ XML-XPath-1.13.01/META.yml 2005-03-02 10:09:50.000000000 +0100 @@ -0,0 +1,11 @@ +# http://module-build.sourceforge.net/META-spec.html +#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# +name: XML-XPath +version: 1.13.01 +version_from: XPath.pm +installdirs: site +requires: + XML::Parser: 2.23 + +distribution_type: module +generated_by: ExtUtils::MakeMaker version 6.17 diff -Naur XML-XPath-1.13/XPath/Expr.pm XML-XPath-1.13.01/XPath/Expr.pm --- XML-XPath-1.13/XPath/Expr.pm 2003-01-26 20:33:24.000000000 +0100 +++ XML-XPath-1.13.01/XPath/Expr.pm 2004-05-22 12:29:04.000000000 +0200 @@ -330,7 +330,7 @@ sub op_le { my ($node, $lhs, $rhs) = @_; - op_gt($node, $rhs, $lhs); + op_ge($node, $rhs, $lhs); } sub op_ge { @@ -359,31 +359,21 @@ !$rh_results->isa('XML::XPath::NodeSet'))) { # (that says: one is a nodeset, and one is not a nodeset) - my ($nodeset, $other); - my ($true, $false); if ($lh_results->isa('XML::XPath::NodeSet')) { - $nodeset = $lh_results; - $other = $rh_results; - # we do this because unlike ==, these ops are direction dependant - ($false, $true) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True); + foreach my $node ($lh_results->get_nodelist) { + if ($node->to_number->value >= $rh_results->to_number->value) { + return XML::XPath::Boolean->True; + } + } } else { - $nodeset = $rh_results; - $other = $lh_results; - # ditto above comment - ($true, $false) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True); - } - - # True if and only if there is a node in the - # nodeset such that the result of performing - # the comparison on <type>(string_value($node)) - # is true. - foreach my $node ($nodeset->get_nodelist) { - if ($node->to_number->value >= $other->to_number->value) { - return $true; + foreach my $node ($rh_results->get_nodelist) { + if ( $lh_results->to_number->value >= $node->to_number->value) { + return XML::XPath::Boolean->True; + } } - } - return $false; + } + return XML::XPath::Boolean->False; } else { # Neither is a nodeset if ($lh_results->isa('XML::XPath::Boolean') || @@ -429,31 +419,21 @@ !$rh_results->isa('XML::XPath::NodeSet'))) { # (that says: one is a nodeset, and one is not a nodeset) - my ($nodeset, $other); - my ($true, $false); if ($lh_results->isa('XML::XPath::NodeSet')) { - $nodeset = $lh_results; - $other = $rh_results; - # we do this because unlike ==, these ops are direction dependant - ($false, $true) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True); + foreach my $node ($lh_results->get_nodelist) { + if ($node->to_number->value > $rh_results->to_number->value) { + return XML::XPath::Boolean->True; + } + } } else { - $nodeset = $rh_results; - $other = $lh_results; - # ditto above comment - ($true, $false) = (XML::XPath::Boolean->False, XML::XPath::Boolean->True); - } - - # True if and only if there is a node in the - # nodeset such that the result of performing - # the comparison on <type>(string_value($node)) - # is true. - foreach my $node ($nodeset->get_nodelist) { - if ($node->to_number->value > $other->to_number->value) { - return $true; + foreach my $node ($rh_results->get_nodelist) { + if ( $lh_results->to_number->value > $node->to_number->value) { + return XML::XPath::Boolean->True; + } } - } - return $false; + } + return XML::XPath::Boolean->False; } else { # Neither is a nodeset if ($lh_results->isa('XML::XPath::Boolean') || @@ -566,8 +546,7 @@ $results->push($rhnode) unless exists $found{"$rhnode"}; } - $results->sort; - return $results; + return $results->sort->remove_duplicates; } die "Both sides of a union must be Node Sets\n"; } diff -Naur XML-XPath-1.13/XPath/LocationPath.pm XML-XPath-1.13.01/XPath/LocationPath.pm --- XML-XPath-1.13/XPath/LocationPath.pm 2001-03-16 12:10:08.000000000 +0100 +++ XML-XPath-1.13.01/XPath/LocationPath.pm 2004-05-22 12:25:14.000000000 +0200 @@ -55,7 +55,7 @@ $nodeset = $step->evaluate($nodeset); } - return $nodeset; + return $nodeset->remove_duplicates; } 1; diff -Naur XML-XPath-1.13/XPath/NodeSet.pm XML-XPath-1.13.01/XPath/NodeSet.pm --- XML-XPath-1.13/XPath/NodeSet.pm 2002-09-02 12:25:47.000000000 +0200 +++ XML-XPath-1.13.01/XPath/NodeSet.pm 2004-05-22 12:25:44.000000000 +0200 @@ -21,6 +21,19 @@ return $self; } +sub remove_duplicates { + my $self = CORE::shift; + my @unique; + my $last_node=0; + foreach my $node (@$self) { + push @unique, $node unless( $node == $last_node); + $last_node= $node; + } + @$self= @unique; + return $self; +} + + sub pop { my $self = CORE::shift; CORE::pop @$self; diff -Naur XML-XPath-1.13/t/test_comp_bug.t XML-XPath-1.13.01/t/test_comp_bug.t --- XML-XPath-1.13/t/test_comp_bug.t 1970-01-01 01:00:00.000000000 +0100 +++ XML-XPath-1.13.01/t/test_comp_bug.t 2005-03-02 10:08:02.000000000 +0100 @@ -0,0 +1,31 @@ +#!/usr/bin/perl -w +use strict; +use XML::XPath; +use Test::More; + +my $xml='<root att="root_att"><daughter att="3"/><daughter +att="4"/><daughter att="5"/></root>'; +my %results= ( '/root/daughter[@att<"4"]' => 'daughter[3]', + '/root/daughter[@att<4]' => 'daughter[3]', + '//daughter[@att<4]' => 'daughter[3]', + '/root/daughter[@att>4]' => 'daughter[5]', + '/root/daughter[@att>5]' => '', + '/root/daughter[@att<3]' => '', + ); + +plan tests => scalar keys %results; + +my $xpath = XML::XPath->new( xml => $xml); + +foreach my $path ( keys %results) + { + my @xpath_result = $xpath->findnodes( $path); + is( dump_nodes( @xpath_result) => $results{$path}, "path: $path"); + } + + +sub dump_nodes + { return join '-', map { $_->getName . "[" . $_->getAttribute( 'att') +. "]" } @_ } + +