Reputation: 562
I try to call subroutine for each tag, but the end_tag_handlers
is never invoked.
My aim is a this sequence:
---sequence---
when <auto>
call \&loading
.
when <apps><title>
call \&kicks
.
when <apps><logs>
call \&bye
.
when <apps>
call \&app
.
when <apps><title>
call \&kicks
.
when <apps><logs>
call \&bye
.
when <apps>
call \&app
.
when </auto>
call \&finish
. → It was not called.
temp.pl:
#!/usr/local/bin/perl -w
use XML::Twig;
my $twig = XML::Twig->new(
start_tag_handlers =>
{ 'auto' => \&loading
},
twig_handlers =>
{ 'apps/title' => \&kicks,
'apps/logs' => \&bye
},
twig_roots =>
{ 'apps' => \&app
},
end_tag_handlers =>
{ 'auto' => \&finish
}
);
$twig -> parsefile( "doc.xml");
sub loading {
print "---loading--- \n";
}
sub kicks {
my ($twig, $elt) = @_;
print "---kicks--- \n";
print $elt -> text;
print " \n";
}
sub app {
my ($twig, $apps) = @_;
print "---app--- \n";
print $apps -> text;
print " \n";
}
sub bye {
my ($twig, $elt) = @_;
print "---bye--- \n";
print $elt->text;
print " \n";
}
sub finish {
print "---fishish--- \n";
}
doc.xml:
<?xml version="1.0" encoding="UTF-8"?>
<auto>
<apps>
<title>watch</title>
<commands>set,start,00:00,alart,end</commands>
<logs>csv</logs>
</apps>
<apps>
<title>machine</title>
<commands>down,select,vol_100,check,line,end</commands>
<logs>dump</logs>
</apps>
</auto>
output:
C:\>perl temp.pl
---loading---
---kicks---
watch
---bye---
csv
---app---
watchset,start,00:00,alart,endcsv
---kicks---
machine
---bye---
dump
---app---
machinedown,select,vol_100,check,line,enddump
I would like more here.
---finish---
Upvotes: 3
Views: 269
Reputation: 67048
From the docs for XML::Twig:
end_tag_handlers
A hash { expression => \&handler}. Sets element handlers that are called when the element is closed (at the end of the XML::Parser End handler). The handlers are called with 2 params: the twig and the tag of the element.
twig_handlers
are called when an element is completely parsed, so why have this redundant option? There is only one use forend_tag_handlers
: when using thetwig_roots
option, to trigger a handler for an element outside the roots.
You're setting up an end handler for your auto
element, which is the root. And you're only using twig_roots
for apps
. So the end handler will never be called.
You should install your handler using twig_handlers
instead.
So try this:
my $twig = XML::Twig->new(
start_tag_handlers =>
{ 'auto' => \&loading
},
twig_handlers =>
{ 'apps/title' => \&kicks,
'apps/logs' => \&bye,
'auto' => \&finish
},
twig_roots =>
{ 'apps' => \&app
},
);
Upvotes: 6