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
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.