Skip Menu |

This queue is for tickets about the XML-XPathEngine CPAN distribution.

Report information
The Basics
Id: 81577
Status: open
Priority: 0/
Queue: XML-XPathEngine

People
Owner: Nobody in particular
Requestors: parlay [...] yopmail.com
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: (no value)
Fixed in: (no value)



Subject: Fails to find camelCase attribute names
attached is a diff that demonstrates that XML::XPathEngine cannot find camelcase attribute names, like "a[@fooBar]".
Subject: camelcase.diff
--- 01_basic.t 2012-11-30 14:22:35.000000000 +0000 +++ /tmp/01_basic.t 2011-10-14 13:35:31.000000000 +0000 @@ -25,26 +25,23 @@ my $kid_nodes= $xp->findvalue( '/root/kid0', $tree); is( $kid_nodes, 'vkid2vkid4', q{findvalue( '/root/kid0', $tree)}); } - { -my @nodes= $xp->findnodes( '//*[@fooBar]', $tree); -is( scalar @nodes, 1, q{findnodes( '//*[@fooBar]', $tree)}); is( $xp->findvalue( '//*[@att2="vv"]', $tree), 'gvkid1gvkid2gvkid3gvkid4gvkid5', q{findvalue( '//*[@att2="vv"]', $tree)} ); -is( $xp->findvalue( '//*[@att2]', $tree), 'gvkid1gkid2 1gkid3 1gvkid2gkid2 2gkid3 2gvkid3gkid2 3gkid3 3gvkid4gkid2 4gkid3 4gvkid5gkid2 5gkid3 5', +is( $xp->findvalue( '//*[@att2]', $tree), 'gvkid1gkid2 1gvkid2gkid2 2gvkid3gkid2 3gvkid4gkid2 4gvkid5gkid2 5', q{findvalue( '//*[@att2]', $tree)} ); } is( $xp->findvalue( '//kid1[@att1=~/v[345]/]', $tree), 'vkid3vkid5', "match on attributes"); -is( $xp->findvalue( '//@*', $tree), 'i1v1i2v1i3vvi4vx1i5val1i6v2i7vvi8vx0i9val0i10v3i11vvi12vx1i13val1i14v4i15vvi16vx0i17val0i18v5i19vvi20vx1i21val1i22', 'match all attributes'); -is( $xp->findvalue( '//@*[parent::*/@att1=~/v[345]/]', $tree), 'v3i11v4i15v5i19', 'match all attributes with a test'); +is( $xp->findvalue( '//@*', $tree), 'i1v1i2v1i3vvi4vx1i5v2i6vvi7vx0i8v3i9vvi10vx1i11v4i12vvi13vx0i14v5i15vvi16vx1i17', 'match all attributes'); +is( $xp->findvalue( '//@*[parent::*/@att1=~/v[345]/]', $tree), 'v3i9v4i12v5i15', 'match all attributes with a test'); is( $xp->findvalue( '//kid1[@att1="v3"]/following::gkid2[1]', $tree), 'gkid2 4', "following axis[1]"); is( $xp->findvalue( '//kid1[@att1="v3"]/following::gkid2[2]', $tree), 'gkid2 5', "following axis[2]"); -is( $xp->findvalue( '//kid1[@att1="v3"]/following::kid1/*', $tree), 'gvkid5gkid2 5gkid3 5', "following axis"); +is( $xp->findvalue( '//kid1[@att1="v3"]/following::kid1/*', $tree), 'gvkid5gkid2 5', "following axis"); is( $xp->findvalue( '//kid1[@att1="v3"]/preceding::gkid2[1]', $tree), 'gkid2 2', "preceding axis[1]"); is( $xp->findvalue( '//kid1[@att1="v3"]/preceding::gkid2[2]', $tree), 'gkid2 1', "preceding axis[1]"); is( $xp->findvalue( '//kid1[@att1="v3"]/preceding::gkid2', $tree), 'gkid2 1gkid2 2', "preceding axis"); @@ -74,7 +71,7 @@ is( $xp->findvalue( 'substring-after((id("i2")//*[1])/@att2, "v")', $tree), 'v', 'substring-after(id())'); is( join( '|', $xp->findvalues( '//kid1[@att1=~/v[345]/]', $tree)), 'vkid3|vkid5', "findvalues match on attributes"); -is( join( '|', $xp->findvalues( '//kid1[@att1=~/v[345]/]/@id', $tree)), 'i11|i19', "findvalues on attributes"); +is( join( '|', $xp->findvalues( '//kid1[@att1=~/v[345]/]/@id', $tree)), 'i9|i15', "findvalues on attributes"); is( $xp->findvalue( '2', $tree), 2, 'findvalues on a litteral'); is( $xp->findvalue( '//gkid1="gvkid1"', $tree), 1, 'findvalues on a litteral'); @@ -102,8 +99,6 @@ $gkid1->add_as_last_child_of( $kid); my $gkid2= tree->new( 'att', name => 'gkid2', value => "gkid2 $_", att2 => "vx", att3 => $_ % 2, id => "i" . ++$id); $gkid2->add_as_last_child_of( $kid); - my $gkid3= tree->new( 'att', name => 'fooBar', value => "gkid3 $_", att2 => "val", att3 => $_ % 2, id => "i" . ++$id); - $gkid3->add_as_last_child_of( $kid); } $tree->set_pos;
Subject: Re: [rt.cpan.org #81577] Fails to find camelCase attribute names
Date: Fri, 30 Nov 2012 17:43:24 +0100
To: bug-XML-XPathEngine [...] rt.cpan.org
From: mirod <xmltwig [...] gmail.com>
On 11/30/2012 03:23 PM, parlay via RT wrote: Show quoted text
> Fri Nov 30 09:23:47 2012: Request 81577 was acted upon. > Transaction: Ticket created by parlay > Queue: XML-XPathEngine > Subject: Fails to find camelCase attribute names > Broken in: (no value) > Severity: Critical > Owner: Nobody > Requestors: parlay@yopmail.com > Status: new > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=81577 > > > > attached is a diff that demonstrates that XML::XPathEngine cannot find > camelcase attribute names, like "a[@fooBar]". >
Could you describe what the additional test, I am not sure I understand it. I don't see anything in the code that would do insensitive case matching. Testing it with XML::Twig::XPath, which uses XML::XPathEngine, I get what I want I have tried many variations of the basic test below, which all give me the proper result: perl -MXML::Twig::XPath -E'$d=q{<d><e fooBar="fooBar1"> elt fooBar 1 </e><e foobar="foobar"> elt foobar </e><e fooBar="fooBar2"> elt fooBar2 </e><e>NOK</e></d>}; $t= XML::Twig::XPath->parse( $d); say $t->findvalue( q{//*[@*]})' # elt fooBar 1 elt foobar elt fooBar2 So I am not sure what the problem is, and whether it's in code or in the test (including the crude dom mockup I set up for the test). Thanks -- mirod
From: parlay [...] yopmail.com
On Fri Nov 30 11:44:27 2012, xmltwig@gmail.com wrote: Show quoted text
> > camelcase attribute names, like "a[@fooBar]". > >
> > Could you describe what the additional test, I am not sure I
understand it. Show quoted text
> > I don't see anything in the code that would do insensitive case matching. > > Testing it with XML::Twig::XPath, which uses XML::XPathEngine, I get > what I want > > I have tried many variations of the basic test below, which all give me > the proper result: > > perl -MXML::Twig::XPath -E'$d=q{<d><e fooBar="fooBar1"> elt fooBar 1 > </e><e foobar="foobar"> elt foobar </e><e fooBar="fooBar2"> elt fooBar2 > </e><e>NOK</e></d>}; $t= XML::Twig::XPath->parse( $d); say > $t->findvalue( q{//*[@*]})' > > # elt fooBar 1 elt foobar elt fooBar2 > > So I am not sure what the problem is, and whether it's in code or in the > test (including the crude dom mockup I set up for the test). > > Thanks >
The additional test was looking for '//*[@fooBar]'. I had to make a lot of other changes in the diff to fix the other tests that broke because of the additional node. Your test case doe works for me. It's possible that the additional node I added didn't result in the XML i expected, but the test failed for me and passed for you. I actually ran across this bug first with Web::Scraper, and narrowed it down to HTML::TreeBuilder::XPath, but maybe went too far and assumed it was XML::XPathEngine. Luckily you're the author of the two latter ones :) I attached a test script showing that the html case-normalization in HTML::TreeBuilder::XPath is the issue. If an attribute occurs as camelCase in the HTML, it gets lowercased by H::T::X, but the xpath query doesn't, so it can't find the node.
Subject: d.pl
#!/usr/bin/env perl use strict; use warnings; use HTML::TreeBuilder::XPath; my $html = q[ <div class="sidebar"> <ul id="followShare"> <li><a class="btn green" saveLink="true" href="http://delicious.com/" style="margin-right:5px;">Save Link</a></li> <li><a class="shareLink btn white" shareLink="true" title="Delicious" url="http://delicious.com/">Share Link</a></li> </ul> </div> ]; my $t = HTML::TreeBuilder::XPath->new; $t->store_comments(1) if ($t->can('store_comments')); $t->ignore_unknown(0); $t->parse($html); $t->eof; # This doesn't work, it finds 0 nodes. my @nodes = $t->findnodes('//a[@saveLink]'); print '//a[@saveLink]: found ', scalar @nodes, " nodes\n"; # This works, it finds 1 node. @nodes = $t->findnodes('//a[@savelink]'); print '//a[@savelink]: found ', scalar @nodes, " nodes\n";