holli has asked for the wisdom of the Perl Monks concerning the following question:

Brethren & Sisters,

I expected the code below (simplified example) to print "AB", instead I get a Can't call method "att" without a package or object reference at foo.pl line 17 and I simply don't grok why. Can someone shed some light on that?
use warnings; use strict; use Data::Dumper; use XML::Twig; my $t= XML::Twig->new ( twig_handlers => { '/foo/bar' => sub { my $bay = $_->get_xpath('bay'); my $baz = $_->get_xpath('baz'); print $bay->att("V"); print $baz->att("V"); } } ); $t->parse(join("", <DATA>)); __DATA__ <foo> <bar> <bay V="A" /> <baz V="B" /> </bar> </foo>


holli, /regexed monk/

Replies are listed 'Best First'.
Re: XML::Twig oddity
by mirod (Canon) on Jan 29, 2007 at 13:48 UTC

    get_xpath returns a list (see the docs), so in your case when you write $bay = $_->get_xpath('bay'), $bay, gets assigned the number of elements in the list, presumably 1.

    I believe what you want is $bay= $_->first_child( 'bay');. You can also use $bay = $_->get_xpath('bay', 0), but I believe it is much less clear than simply using first_child.

Re: XML::Twig oddity
by convenientstore (Pilgrim) on Nov 15, 2008 at 05:24 UTC
    I am just going through all XML::Twig posts and ran to this one and was just testing out the code..
    use strict; use warnings; use XML::Twig; my $xml = <<XML <foo> <bar> <bay V="A" /> <baz V="B" /> </bar> </foo> XML my $t = XML::Twig->new ( twig_handlers => { '/foo/bar' => sub { my $bay = $_->first_child('bay'); my $baz = $_->first_child('baz'); print $bay->att("V"); print $baz->att("V"); } } ); $t->parse ($xml);
    but it says
    ./xml_test1.pl syntax error at ./xml_test1.pl line 17, near "my " Global symbol "$t" requires explicit package name at ./xml_test1.pl li +ne 17. Can't use global $_ in "my" at ./xml_test1.pl line 21, near "= $_" syntax error at ./xml_test1.pl line 26, near "}" Execution of ./xml_test1.pl aborted due to compilation errors.
    what am I doing wrong?
      that was silly of me
      thank you for pointing it out
      use strict; use warnings; use XML::Twig; my $xml = <<XML; <foo> <bar> <bay V="A" /> <baz V="B" /> </bar> </foo> XML my $t = XML::Twig->new ( twig_handlers => { '/foo/bar' => sub { my $bay = $_->first_child('bay'); my $baz = $_->first_child('baz'); print $bay->att("V"); print $baz->att("V"); } } ); $t->parse ($xml);
        hi :) you should also click the correct "reply" link, or "comment on" link, that way you avoid talking to yourself, and readers can follow what is going on :)