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