Skip Menu |

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

Report information
The Basics
Id: 12778
Status: resolved
Priority: 0/
Queue: XML-Twig

People
Owner: Nobody in particular
Requestors: cjb [...] seirad.com
Cc:
AdminCc:

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



Subject: Variable scope and TwigHandlers
Debian 3.1 Kernel 2.6.10 Package libxml-twig-perl 3.17 I'm using a TwigHandler to loop through the many children of the root of an XML file, and write certain parts to a database. I can't pass parameters into the handler function (can I?) so I'm creating the $dbh with global scope like in the examples. I'm also creating a simple counter with global scope and incrementing it inside the handler. In the first loop of the handler the counter appears to be undef. However, in subsequent loops it increments properly. A database handle initialized in the main program also appears undef inside the handler. I've had to put a nasty condition in the handler to check if these vars are defined, to take care of the first call. This code reproduces the problem: #!/usr/bin/perl -w use strict; use XML::Twig; use DBD::mysql; my $twig= new XML::Twig(TwigHandlers => {entry => \&entry,}); $twig->parsefile("uniprot_sprot.xml"); my $entry_id = 1; # Need these to be global my $dbh = dbconnect(); sub dbconnect { my $database = ""; my $host = ""; my $user = ""; my $password = ""; my $dsn = "DBI:mysql:$database:$host"; my $dbh = DBI->connect($dsn,$user,$password,{AutoCommit => 0, PrintError => 1}) or die "No database handle\n"; return $dbh; } sub entry { my ($twig,$entry) = @_; $entry_id = 1 if (!defined $entry_id); # These lines are needed to get these $dbh = dbconnect() if (!defined $dbh); # vars to be defined in the first call # without the above lines I get the error shown at the bottom # Otherwise it works fine my $organism = $entry->first_child('organism'); my $taxid = organism($organism) if (defined $organism); my $sql = "insert into entry (entry_id, taxonomy_id) values ($entry_id,$taxid)"; print STDERR $sql; print STDERR "\n"; my $sth = $dbh->prepare($sql); $sth->execute(); $sth->finish(); $entry_id++; $twig->purge; } $twig->purge; sub organism { my $organism = shift; my $dbreference = $organism->first_child('dbReference'); my $taxid = $dbreference->{'att'}->{'id'}; return $taxid; } Use of uninitialized value in concatenation (.) or string at parser.pl line 35. insert into entry (entry_id, taxonomy_id) values (,5875) Can't call method "prepare" on an undefined value at parser.pl line 38.
Date: Thu, 12 May 2005 20:27:25 +0200
From: Michel Rodriguez <mirod [...] xmltwig.com>
To: bug-XML-Twig [...] rt.cpan.org
Subject: Re: [cpan #12778] Variable scope and TwigHandlers
RT-Send-Cc:
Guest via RT wrote: my $twig= new XML::Twig(TwigHandlers => {entry => \&entry,}); $twig->parsefile("uniprot_sprot.xml"); my $entry_id = 1; # Need these to be global my $dbh = dbconnect(); Did you try doing the dbconnect and creating $entry_id _before_ parsing the file and using them? In other words swapping the 2 2-line parts? Show quoted text
> I'm using a TwigHandler to loop through the many children of the > root of an XML file, and write certain parts to a database. > I can't pass parameters into the handler function (can I?)
Before I look further into this, yes you can pass parameters to the handler. You just need to use a closure (big word, but easy to use ;--) my $twig= new XML::Twig(TwigHandlers => { entry => sub { entry( @_, $dbh, $entry_id); $entry_id++; }, } ); sub entry { my( $twig, $elt, $dbh, $entry_id)= @_; ... } For explanations about closures, see http://www.perl.com/lpt/a/2002/05/29/closure.html Does this help -- Michel Rodriguez Perl &amp; XML xmltwig.com
Show quoted text
> Did you try doing the dbconnect and creating $entry_id _before_ parsing > the file and using them? In other words swapping the 2 2-line parts?
That fixed it. Now you pointed it out is seems obvious, sorry to waste time. The script was never getting to the global defs for my vars. I'll look at closures, too. This module is the easiest XML handling I've ever done. THANKS.