Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

TWig handler generation

by nico38100 (Novice)
on Feb 01, 2019 at 14:21 UTC ( #1229233=perlquestion: print w/replies, xml ) Need Help??

nico38100 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Guys, I have a question on a twig module. Do you know the way to build the twig_handler with variables, I show you below what I would like to do

my $test = sub { $_->delete()}; my $node_to_delete = 'node1-node2-node3-node4'; my @tags = split('-', $node_to_delete ); // my objective with a foreach will be to get a varaible // my $handlers = {$tags[0] => $test, $tags[1] => $test ) my $twig = new XML::Twig( twig_handlers => { $twig_handlers,}); $twig->parsefile(*DATA);
If you have any idea to do this . Many Thanks Nicolas

Replies are listed 'Best First'.
Re: TWig handler generation
by holli (Abbot) on Feb 01, 2019 at 15:02 UTC
    You're close.
    my $del_handler = sub { $_->delete() }; my $node_to_delete = 'node1-node2-node3-node4'; my @tags = split('-', $node_to_delete ); my $handlers = { map { $_ => $del_handler } @tags }; my $twig = new XML::Twig( twig_handlers => $handlers ); $twig->parsefile(*DATA);


    You can lead your users to water, but alas, you cannot drown them.
      Hello holli Thanks for your email, I tried what you post but it doesn't seem to work. Here my code instead of having *Data I am parsing a file . Here the code
      @elements = split('-', $elements_to_treat); if ($subject[0] eq 'delete_node'){ print "Delete Node ".$element."\n " if ($dbgFlag == 1); &delete_node(@elements,$file_to_read); } sub delete_node { #--------------------------------------------------------------------- +--------- my ($elements,$file_to_read) = @_; my $del_handler = sub { $_->delete()}; my @all_element = @{$elements}; my $handlers = {map {$_ => $del_handler} @all_element}; my $twig = new XML::Twig(twig_handlers => $handlers); $twig->parsefile($file_to_read); }

      And here the results of my parsing which is ending in errror

      Line of configuration file: delete_node:{node1-node2-node3-node4} Element of configuration to treat: 'node1-node2-node3-node4' Delete Node Couldn't open node1: No such file or directory at C:\Users\test\Documents\

      it seems it's created a file but I don't understand why, if you have an idea ? Many Thanks

        You are calling your sub with a an array as "first argument": &delete_node(@elements,$file_to_read);
        But in your sub you expect an arrayref: my ($elements,$file_to_read) = @_;
        You need to pass your data in as a reference. Also, don't call subs with "&". And if your learning material teaches you to, throw it away.

        See if that fixes it.


        You can lead your users to water, but alas, you cannot drown them.
Re: TWig handler generation -- dispatch table
by Discipulus (Abbot) on Feb 01, 2019 at 17:04 UTC
    Hello nico38100

    A dispatch table is useful as an hash reference is the only think the twig_handler wants:

    use strict; use warnings; use XML::Twig; my %dispatch = ( # <-- build it.. to => sub {$_->delete;}, from => sub {$_->set_text( uc($_->trimmed_text) ); $_->flush}, ); my $twig=XML::Twig->new( twig_handlers => \%dispatch , # <-- ..use it! pretty_print => 'indented', ); $twig->parse( *DATA ); __DATA__ <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> #OUT <note> <from>JANI</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>


    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Hello again Discipulus and thanks again for your help here the code that I try below

      my ($elements) = @_; my $del_handler = sub { $_->delete()}; my @all_element = @{$elements}; my %test; foreach $element(@all_element){ $test{$element}= \&del_handler; } open my $file_end, '>', $file_to_read.'-parsed_'.$dateLog.'.xml'; my $twig = new XML::Twig( twig_handlers => {\%test, _default_ => sub { $_[0]->flush($file_end)}} +); $twig->parsefile($file_to_read); close $file_end;

      And here the errors

      Delete Node1 unrecognized expression in handler: 'CODE(0x2bc12e8)' at C:\Users\doc\ line 125.

        It helps if you post a complete runnable script

        #!/usr/bin/perl use strict; use warnings; use XML::Twig; use Time::Piece; my $file_to_read = 'input.xml'; my @elements_to_treat = qw(node1 node2 node3); delete_node(\@elements_to_treat); sub delete_node { my ($all_elements) = @_; my %handlers; for my $element (@$all_elements){ $handlers{$element} = sub { $_->delete() }; } my $dateLog = localtime->ymd('_'); my $file_to_write = $file_to_read.'-parsed_'.$dateLog.'.xml'; open my $fh_out, '>', $file_to_write or die "Could not open $file_to_write : $!"; $handlers{ '_default_' } = sub { $_[0]->flush($fh_out) }; my $twig = new XML::Twig( twig_handlers => \%handlers, pretty_print => 'indented', ); $twig->parsefile($file_to_read); close $fh_out; print "Created $file_to_write\n"; }

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1229233]
Approved by marto
Front-paged by haukex
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2021-10-26 06:40 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (90 votes). Check out past polls.