Skip Menu |

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

Report information
The Basics
Id: 128284
Status: new
Priority: 0/
Queue: XML-XPath

People
Owner: Nobody in particular
Requestors: NEILB [...] cpan.org
Cc:
AdminCc:

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



Subject: findvalue() on a node from findnodes() returns surprising value
First, let's say you've got a file shop.xml, which looks like this: <?xml version="1.0" encoding="utf-8"?> <shop> <grocery> <fruit name="cherry"> <color> red </color> </fruit> <fruit name="banana"> <color> yellow </color> </fruit> </grocery> </shop> I want to iterate over the fruit, printing out the color of each fruit in turn: use File::Slurper qw/ read_text /; use XML::XPath; my $metadata = read_text($ARGV[0]); my $xpath = XML::XPath->new( xml => $metadata); for my $node ($xpath->findnodes('//shop/grocery/fruit')) { my $name = $node->getAttribute('name'); print STDERR "\nNAME: $name\n"; my $color = $node->findvalue("//color"); print STDERR "COLOUR: $color\n"; } This doesn't return the result I expect. Instead I get this: NAME: cherry COLOUR: red yellow NAME: banana COLOUR: red yellow So it gets the node name right, but it's pulling in the content from all nodes, rather than the selected node. The code for findvalue() XML::XPath::Node is this: sub findvalue { my $node = shift; my ($path) = @_; my $xp = XML::XPath->new(); return $xp->findvalue($path, $node); } If I change it to this: sub findvalue { my ($node, $path) = @_; my $xp = XML::XPath->new(xml => XML::XPath::XMLParser::as_string($node)); return $xp->findvalue($path); } Then my example produces the expected output: NAME: cherry COLOUR: red NAME: banana COLOUR: yellow This is a naive fix though, as I haven't thought through the implications if you're using set_namespace(). This is a simple example distilled out of a problem I've hit with how Net::SAML2 is using XML::XPath. I'll do some more investigation, but wanted to log this much, in case my understanding of XPath or XML::XPath is wrong. Cheers, Neil