You can't do that. '/document/header[2]' should trigger an error, [2] is not supported. You will need to call the handler on all headers, and manage the state yourself to see if you have deleted the second one.
This should work, by keeping track taht the second header has already been deleted in a hidden attribute in the parent:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig_to_del=XML::Twig->new(
twig_handlers=>{
#to_delete elements
'/document/header'=>\&element_
+delete,
},
)
->parse(\*DATA)
->print;
sub element_delete
{
my ($twig, $element)= @_;
my $first_header= $element->prev_sibling( 'header');
if( $first_header && ! $first_header->att( '#header_deleted'))
{ $element->delete;
$first_header->set_att( '#header_deleted' => 1);
}
}
__DATA__
<document>
<header>h1</header>
<header>h2</header>
<header>h3</header>
</document>
Of course if you want to delete all headers after the first one, which is more likely, the code is much simpler, you just have to delete any header after the first one:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig_to_del=XML::Twig->new(
twig_handlers=>{
#to_delete elements
'/document/header'=> sub { $_-
+>delete if $_->prev_sibling( 'header'); },
},
)
->parse(\*DATA)
->print;
__DATA__
<document>
<header>h1</header>
<header>h2</header>
<header>h3</header>
</document>
|