Skip Menu | You are currently an anonymous guest. | Login | Return to Main | About rt.cpan.org
 

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.

X Report information
Id: 6363
Status: new
Left: 0 min
Priority: 0/0
Queue: XML-XPath

Owner: Nobody
Requestors: MIROD <MIROD [...] cpan.org>
Cc:
AdminCc:

Severity: Important
Broken in: 1.13
Fixed in: (no value)




X History Display mode: Brief headersFull headers
#   Wed May 19 10:46:46 2004 MIROD - Ticket created  
Subject: using < in a query returns results as if <= had been used
[text/plain 1k]
Checking the results of queries using < against XML::LibXML returns failures.

I went through the code with the debugger, evaluate goes properly into op_lt, which switches arguments and goes to op_gt, but then I can't figure out why it returns 1 for lh and rh both equal to 4.

#!/usr/bin/perl -w
use strict;
use XML::XPath;
use XML::LibXML;
use Test::More qw(no_plan);

my $xml='<root att="root_att"><daughter att="3"/><daughter att="4"/><daughter att="5"/></root>';
my @queries= ( '/root/daughter[@att<"4"]', '/root/daughter[@att<4]', '//daughter[@att<4]',
'/root/daughter[@att>4]', # this one is OK
);

my $xpath = XML::XPath->new( xml => $xml);
my $libxml = XML::LibXML->new->parse_string( $xml);

foreach my $path ( @queries)
{ print "find( '$path'):\n";
my @xpath_result = $xpath->findnodes( $path);
my @libxml_result= $libxml->findnodes( $path);
is( dump_nodes( @xpath_result) => dump_nodes( @libxml_result), "path: $path");
}


sub dump_nodes
{ return join '-', map { $_->getName . "[" . $_->getAttribute( 'att') . "]" } @_ }

#   Wed May 19 11:47:25 2004 MIROD - Correspondence added  
[text/plain 1k]
[MIROD - Wed May 19 10:46:46 2004]:

OK, I got it,

You were swapping things arouond so much in op_gt that you ended up not
reversing the test properly and doing !b<a instead of a<b.

Patch on Expr.pm attached, test below:

#!/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')
. "]" } @_ }

__
Mirod
[text/x-diff 1.6k]
--- Expr.pm 2003-01-26 20:33:24.000000000 +0100
+++ Expr.pm.new 2004-05-19 19:39:22.261681184 +0200
@@ -430,29 +430,21 @@
# (that says: one is a nodeset, and one is not a nodeset)

my ($nodeset, $other);
- my ($true, $false);
+ my ($true, $false)= ( XML::XPath::Boolean->True, XML::XPath::Boolean->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 $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 $true;
+ }
}
- }
+ }
return $false;
}
else { # Neither is a nodeset

#   Wed May 19 13:24:08 2004 MIROD - Correspondence added  
[text/plain 123b]
[MIROD - Wed May 19 11:47:25 2004]:

There was a similar problem in op_ge, which is fixed in the attached Expr.pm

__
Mirod
[application/octet-stream 23.8k]
Message body not shown because it is too large or is not plain text.
#   Wed May 19 14:54:48 2004 MIROD - Correspondence added  
[text/plain 201b]
[MIROD - Wed May 19 13:24:08 2004]:

> [MIROD - Wed May 19 11:47:25 2004]:
>
> There was a similar problem in op_ge, which is fixed in the attached
Expr.pm

Oops, wrong file! This one's good,
__
Mirod
[application/octet-stream 23.7k]
Message body not shown because it is too large or is not plain text.
#   Wed Mar 02 05:06:46 2005 MIROD - Correspondence added  
[text/plain 300b]
Considering this bug has been open for quite a while, the fix available
for about the same time, and I have a few modules now that depend on
XML::XPath, I have published a patched version at:

http://xmltwig.com/xml-xpath-patched/

I should not be too difficult to update XML::XPath itself.

__
mirod