#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_handlers => 
    { # mark titles and their ancestors as keepers
      # '#att' attributes are not output by flush
      title => sub { foreach my $keep ( $_, $_->ancestors) 
                       { $keep->set_att( '#keep' => 1); }
                   },
      # called for all elements (including titles)  
      _all_ => sub { if( $_->att( '#keep')) { $_->flush;  }
                     else                   { $_->delete; }
                   },
    },
                pretty_print => 'indented',
              )
         ->parse( \*DATA);       

__DATA__
<?xml version="1.0" ?>
<book>
  <title>My Book</title>
  <chapters>
    <chapter>
      <title>First Title</title>
      <num>1</num>
      <text>chapter 1 text</text>
      <section>
        <title>Section 1.1 title</title>
        <p>section text</p>
      </section>
    </chapter>
    <chapter>
      <title>Second Title</title>
      <num>2</num>
      <text>chapter 2 text</text>
    </chapter>
    <index>
      <title>Index</title>
      <text>index text.</text>
    </index>
  </chapters>
</book>
