CJ7
CJ7

Reputation: 23275

HTML::TreeBuilder::XPath findvalue returns concatenation of values

The findvalue function in HTML::TreeBuilder::XPath returns a concatenation of any values found by the xpath query.

Why does it do this, and how could a concatenation of the values be useful to anyone?

Upvotes: 0

Views: 354

Answers (2)

Alex
Alex

Reputation: 45

Use

( $tree->findvalues('//p') )[0] ;

instead.

Upvotes: 1

ThisSuitIsBlackNot
ThisSuitIsBlackNot

Reputation: 24063

Why does it do this?

When you call findvalue, you're requesting a single scalar value. If there are multiple matches, they have to be combined into a single value somehow.

From the documentation for HTML::TreeBuilder::XPath:

findvalue ($path)

...If the path returns a NodeSet, $nodeset->xpath_to_literal is called automatically for you (and thus a Tree::XPathEngine::Literal is returned).

And from the documentation for Tree::XPathEngine::NodeSet:

xpath_to_literal()

Returns the concatenation of all the string-values of all the nodes in the list.

An alternative would be to return the Tree::XPathEngine::NodeSet object so the user could iterate through the results himself, but the findvalues method already returns a list.


How could a concatenation of the values be useful to anyone?

For example:

use strict;
use warnings 'all';
use 5.010;

use HTML::TreeBuilder::XPath;

my $content = do { local $/; <DATA> };
my $tree = HTML::TreeBuilder::XPath->new_from_content($content);

say $tree->findvalue('//p');

__DATA__
<p>HTML is just text.</p>
<p>It can still make sense without the markup.</p>

Output:

HTML is just text.It can still make sense without the markup.

Usually, though, it makes more sense to get a list of matches and iterate through them instead of doing dumb concatenation, so you should use findvalues (plural) if you could have multiple matches.

Upvotes: 2

Related Questions