Re: Passing data to XML::Twig twig_roots callbacks....?
Dustin Suchter <[email protected]>
| Newsgroups | gmane.comp.lang.perl.xml |
|---|---|
| Message-ID | <[email protected]> |
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