#!/usr/bin/perl -w use strict; use XML::Twig; my $t = XML::Twig->new( twig_handlers => { b => \&b, }, pretty_print => 'indented', ); $t->parse( \*DATA); $t->flush; sub b { my ( $t, $b ) = @_; foreach my $c ($b->children('c')) { # yep, that does it: wrap a b element around the c $c->wrap_in( b => { name => $c->att( 'name') } ) } $b->erase; # remove the original b $t->flush; # you need to flush here if you want to free the memory } __DATA__