As long as you don't mind using IO::Tee from cpan to send output to two files at once, the code below works. In the default case you output to both, and in the "thing" case you choose which file (or neither) for output.
use XML::Twig;
use IO::Tee;
open my $frufile, '>', 'fruit.xml' or die "fruit $!";
open my $vegfile, '>', 'veg.xml' or die "veg $!";
my $tee = IO::Tee->new($frufile, $vegfile);
select $tee;
my $twig=XML::Twig->new(
twig_handlers =>
{
thing => \&magic,
_default_ => sub { $_[0]->flush; 1; },
},
pretty_print => 'indented',
empty_tags => 'normal',
);
$twig->parse( *DATA );
sub magic {
my ($thing, $element) = @_;
for ($element->{att}{type}) {
if (/fruit/) {
$thing->flush($frufile);
} elsif (/vegetable/) {
$thing->flush($vegfile);
} else {
$thing->purge;
}
}
1;
}
__DATA__
<batch>
<header>
<foo>1</foo>
<bar>2</bar>
<baz>3</baz>
</header>
<thing type="fruit" >Im an apple!</thing>
<thing type="city" >Toronto</thing>
<thing type="vegetable" >Im a carrot!</thing>
<thing type="city" >Melrose</thing>
<thing type="vegetable" >Im a potato!</thing>
<thing type="fruit" >Im a pear!</thing>
<thing type="vegetable" >Im a pickle!</thing>
<thing type="city" >Patna</thing>
<thing type="fruit" >Im a banana!</thing>
<thing type="vegetable" >Im an eggplant!</thing>
<thing type="city" >Taumatawhakatangihangakoauauotamateaturipuk
+akapikimaungahoronukupokaiwhenuakitanatahu</thing>
<trailer>
<chrzaszcz>A</chrzaszcz>
<zdzblo>B</zdzblo>
</trailer>
</batch>