From: Faith Greenwood on
I'm very confused. I'm pulling some numbers from an xml file and then
trying to do some math.

####XML File
<library>
<books>5</books>
<pages>12</pages>
</library>

####Code
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
use XML::XPath;

my $parser=XML::LibXML->new();
my $doc=$parser->parse_file("C:/scripts/production/xml.xml");

my $books=$doc->find("//books/text()");
my $pages=$doc->find("//pages/text()");

print "$books\n";
print "$pages\n";

my $total_pages=$books * $pages;
########################
when I run the above code, I get the output:

5
12
Operation "*": no method found,
left argument in overloaded package XML::LibXML::Nodelist,
right argument in overloaded package XML::LibXML::Nodelist at
script.pl line 16



Why can't I do math operations here?

thx!



From: John Bokma on
Faith Greenwood <fgnowfg(a)gmail.com> writes:

> my $total_pages=$books * $pages;
> ########################
> when I run the above code, I get the output:
>
> 5
> 12
> Operation "*": no method found,
> left argument in overloaded package XML::LibXML::Nodelist,
> right argument in overloaded package XML::LibXML::Nodelist at
> script.pl line 16

You are trying to multiply two Nodelists...

> Why can't I do math operations here?

that's why. You probably have to 1) check that each nodelist has one
item and 2) extract the text out of each node 3) multiply the text
(which Perl will automagically convert to numbers)

--
John Bokma j3b

Hacking & Hiking in Mexico - http://johnbokma.com/
http://castleamber.com/ - Perl & Python Development
From: Daniel Molina Wegener on
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

On S�b 06 Feb 2010 17:13,
Faith Greenwood wrote:

> I'm very confused. I'm pulling some numbers from an xml file and then
> trying to do some math.

OK, no problem...

>
> ####XML File
> <library>
> <books>5</books>
> <pages>12</pages>
> </library>
>
> ####Code
> #!/usr/bin/perl
> use strict;
> use warnings;
> use XML::LibXML;
> use XML::XPath;
>
> my $parser=XML::LibXML->new();
> my $doc=$parser->parse_file("C:/scripts/production/xml.xml");
>
> my $books=$doc->find("//books/text()");
> my $pages=$doc->find("//pages/text()");
>
> print "$books\n";
> print "$pages\n";
>
> my $total_pages=$books * $pages;
> ########################
> when I run the above code, I get the output:
>
> 5
> 12
> Operation "*": no method found,
> left argument in overloaded package XML::LibXML::Nodelist,
> right argument in overloaded package XML::LibXML::Nodelist at
> script.pl line 16

Well, the error is clear. The /find()/ method returns a Nodelist
object, so you are trying to miltiply $books and $pages which are
both XML::LibXML::Nodelist objects.

Try using something like:

$books = int($books->string_value());
$pages = int($pages->string_value());
my $total_pages = $books * $pages;

>
>
>
> Why can't I do math operations here?
>
> thx!


Best regards,
- --
Daniel Molina Wegener <dmw [at] coder [dot] cl>
Software Architect, System Programmer & Web Developer
Phone: +1 (510) 629-4267 | Blog: http://coder.cl/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iQIcBAEBCgAGBQJLbeJSAAoJEHxqfq6Y4O5NsjYP/2oFCmorBcavKkk2yVOHz3Qe
bOWlqiBlpw0oNsNniPFQ3n/tTFeCb/6yNHz/HiEnNsFJT0CL1l7HWjAL7tO/Lz9M
IWoUIOeEfqqDP0s0e34HTfyY1gu8/6jSUCoMsiT319PVVq/Kffp1fP/agY351Hsl
OWQkSYtDG+Q4wVIbLJ1Mxsmv/+H7YkWtRGXNmwjBllIhFYRJZmtzTKx4l3ErQ/Fe
Abw2yjm9M1G9Cl0muwdNuv/QwVequ2tH+MnGKFl03ulXc0Qk/drJDCnoTk2Pseze
6bkSB94rAAMO990rVYaQglsC30x4FHzK2EaH4W5F/2Q/U/4MXWfEgXBZV2YZcLZJ
N2Rnoa6uZVzlEtcwrGFaPnB1/HRpDSL8FaOTvUHYDrdr8auWmPGc9z6twvL9HbVM
g4USyU999wlSJkMyGrjnzjlJb5DCLuueEia+3Cb4XyarVN7b2OHrjq4yFOXW0iTU
/1rpzeAgP68QDs+jJ7JxCD8xXqZBcPTFiCWTxS5yN7DP76QXJNXu6K0SXiL8iY4y
m1ts05A5+FgZgteFk0HmODhwsetRJ/5+U0BAorv1JlYptUB7W0Q0zVyik7lICPa4
2Cm2Yv2lsLrBLtPanzj+8W1xWSB+khLSb1AxIY7znvNoZGObpFTiMoC+RFNPriqX
t3KjPZpRxkug3JkicZxw
=tQzG
-----END PGP SIGNATURE-----

From: Ben Morrow on

Quoth Faith Greenwood <fgnowfg(a)gmail.com>:
> I'm very confused. I'm pulling some numbers from an xml file and then
> trying to do some math.
>
> ####XML File
> <library>
> <books>5</books>
> <pages>12</pages>
> </library>
>
> ####Code
> #!/usr/bin/perl
> use strict;
> use warnings;
> use XML::LibXML;
> use XML::XPath;
>
> my $parser=XML::LibXML->new();
> my $doc=$parser->parse_file("C:/scripts/production/xml.xml");
>
> my $books=$doc->find("//books/text()");
> my $pages=$doc->find("//pages/text()");
>
> print "$books\n";
> print "$pages\n";
>
> my $total_pages=$books * $pages;
> ########################
> when I run the above code, I get the output:
>
> 5
> 12
> Operation "*": no method found,
> left argument in overloaded package XML::LibXML::Nodelist,
> right argument in overloaded package XML::LibXML::Nodelist at
> script.pl line 16

If you add

warn overload::StrVal($books);

before the multiplication, you will see that the 'numbers' are actually
objects with overloaded stringification. Since there is no "*" overload,
and no "0+" overload, and 'fallback => 1' was not specified[1], perl has
no way to perform the multiplication. You can work around this by
explicitly stringifying first:

$books = "$books"; # stringify overloaded object
$pages = "$pages"; # ""

my $total_pages = $books * $pages;

The comment is important so that the next person to look at the code
doesn't mutter 'perldoc -q quote' and remove the lines :).

Ben

[1] I consider the fact that fallback => 1 isn't the default to be a bug
in the perl overloading system, but it's much too late to change
that now. Apart from anything else, any new overloads (like the -X
overload that will be in 5.12) must behave as though fallback=>1
were specified, for compatibility.

From: Ben Morrow on

Quoth dmw(a)coder.cl:
> -----BEGIN PGP SIGNED MESSAGE-----

Please don't do that here.

> Well, the error is clear. The /find()/ method returns a Nodelist
> object, so you are trying to miltiply $books and $pages which are
> both XML::LibXML::Nodelist objects.
>
> Try using something like:
>
> $books = int($books->string_value());

The 'int()' is unnecessary, and unclear (since it implies
$books->string_value might be a float we wish to truncate to an
integer),

Ben