Re: Passing data to XML::Twig twig_roots callbacks....?

Dustin Suchter <[email protected]>
Newsgroups gmane.comp.lang.perl.xml
Message-ID <[email protected]>
Ahh.. I left out one more case that I tried, not that it should
matter since $self is a ref anyway:

sub get_grandchild_info {
  my hash_ref = shift();
  return sub {
    my ($twig, $element) = @_;
    #blah blah, do something print-y here
  }
}

my $xmltwigobj = XML::Twig->new(
     twig_roots => {
       'Information/Child/Grandchild' =>
       get_grandchild_info(\$self),
     }
);

-d

Dustin Suchter wrote:
> So this code runs, but obviously doesn't pass my data. It loops the
> expected number of times, given the XML it is parsing:
> 
> sub get_grandchild_info {
>   my hash_ref = shift();
>   return sub {
>     my ($twig, $element) = @_;
>     #blah blah, do something print-y here
>   }
> }
> 
> my $xmltwigobj = XML::Twig->new(
>      twig_roots => {
>        'Information/Child/Grandchild' =>
>        get_grandchild_info,
>      }
> );
> 
> If I change the object instantiation code to what immediately
> follows, my subroutine executes precisely 1 time only:
> 
> sub get_grandchild_info {
>   my hash_ref = shift();
>   return sub {
>     my ($twig, $element) = @_;
>     #blah blah, do something print-y here
>   }
> }
> 
> my $xmltwigobj = XML::Twig->new(
>      twig_roots => {
>        'Information/Child/Grandchild' =>
>        get_grandchild_info(),
>      }
> );
> 
> And finally this version does the same thing, executing just the
> first time the subroutine is "instantiated" - a term I'll use
> lightly since I believe this is technically a closure-utilizing
> callback, not an object:
> 
> sub get_grandchild_info {
>   my hash_ref = shift();
>   return sub {
>     my ($twig, $element) = @_;
>     #blah blah, do something print-y here
>   }
> }
> 
> my $xmltwigobj = XML::Twig->new(
>      twig_roots => {
>        'Information/Child/Grandchild' =>
>        get_grandchild_info($self),
>      }
> );
> 
> I'm guessing there's something wrong with the prototype for my
> subroutine so $smltwigobj isn't really connecting with
> get_granchild_info when I change the number of args... the question
> is (a) why? and (b) how to fix that?
> 
> 
> Jenda Krynicky wrote:
>> From: Dustin Suchter <[email protected]>
>>> I'm having a hard time wrapping my brain around the idea of using
>>> twig_roots with twig_handlers (specifically so I can pass data back
>>> and forth) in order to process large XML files. Perhaps I'm missing
>>> something obvious, and hopefully someone can help!
>>>
>>> I've got a large XML file currently parsed cleanly using twig_roots
>>> and setting callbacks on various elements:
>>>
>>> my $xmltwigobj = XML::Twig->new(
>>>     twig_roots => {
>>>         'Information/Child/Grandchild' => \&get_grandchild_info,
>>>     }
>>> );
>>>
>>> sub get_grandchild_info {
>>>     my ($twig, $element) = @_;
>>>     #blah blah, do something print-y here
>>> }
>>>
>>> My problem is that I'd like to store the info I parse via
>>> get_grandchild_info somewhere useful, where "useful" is not (a) in a
>>> global or (b) printed somewhere. Specifically, I'd like to pass the
>>> reference to a DBM::Deep object to get_grandchild_info and have any
>>> new info added to the existing DBM::Deep object, but really we
>>> shouldn't need to be specific, I just want something like:
>>>
>>> sub get_grandchild_info_extra {
>>>     my ($twig, $element, $hash_ref) = @_;
>>>     #awesomeness
>>> }
>>>
>>> I found Question 27 at
>>> http://xmltwig.com/xmltwig/XML-Twig-FAQ.html#Q27 to be pretty spot-on
>>> for my needs in terms of data passing, but in the end it didn't help
>>> me since nobody seems to use the twig_roots parsing methodology in
>>> combination with the 'closures' mentioned there (which smell a lot
>>> like globals to me anyway...).
>>>
>>> I'd love to see an example of how to modify my code, above, to allow
>>> me to pass a 3rd argument to my callback subroutine.
>> sub get_grandchild_info {
>> 	my hash_ref = shift();
>> 	return sub {
>>      my ($twig, $element) = @_;
>>      #blah blah, do something print-y here
>>    }
>> }
>>
>> ...
>>
>> my $xmltwigobj = XML::Twig->new(
>>     twig_roots => {
>>         'Information/Child/Grandchild' => 
>> get_grandchild_info(\%DBM_HASH),
>>     }
>> );
>>
>>
>>
>> Sometimes a plain old global is the best solution though.
>>
>> And sometimes it's better to have a look at a different module. Maybe 
>> XML::Rules will end up being easier. Though that of course depends on 
>> your XML and your needs.
>>
>> XML::Rules will take care of remembering the data for you and if you 
>> like you can instruct it to store the data of some tag in a DBM::Deep 
>> hash:
>>
>>
>> use XML::Rules;
>> use DBM::Deep;
>>
>> my $parser = XML::Rules->new(
>> 	start_rules => [
>> 		YourHugeTag => sub {
>> 			my %temp = %{$_[1]};
>> 			tie %{$_[1]}, 'DBM::Deep', $filename;
>> 			%{$_[1]} = %temp;
>> 			1;
>> 		}
>> 	],
>> 	rules => [
>> 		...
>>
>> (or if the tag doesn't have any attributes you'd be interested in
>>
>>
>> my $parser = XML::Rules->new(
>> 	start_rules => [
>> 		YourHugeTag => sub {
>> 			tie %{$_[1]}, 'DBM::Deep', $filename;
>> 			# and maybe 
>> 			# %{$_[1]} = (); 
>> 			# to clear the hash
>> 			1;
>> 		}
>> 	],
>> 	rules => [
>> 		...
>>
>> And now all the data returned by the rules specified for the child 
>> tabs of YourHugeTag  will be stored in the DBM::Deep and be available 
>> in $_[1] within the rule specified for YourHugeTag.
>>
>>
>> Jenda 
>> ===== [email protected] === http://Jenda.Krynicky.cz =====
>> When it comes to wine, women and song, wizards are allowed 
>> to get drunk and croon as much as they like.
>> 	-- Terry Pratchett in Sourcery
>>
>> _______________________________________________
>> Perl-XML mailing list
>> [email protected]
>> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
>>
> 
> 
_______________________________________________
Perl-XML mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.