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