use XML::Smart ; my $xml = XML::Smart->new(q` number list 1 number list 2 ` , 'html'); my $new_xml = XML::Smart->new() ; process($xml , $new_xml) ; print $new_xml->data ; sub process { my $xml = shift ; my $new_xml = shift ; foreach my $node_i ( $xml->nodes ) { my @lines = split(/\s*\n\s*/ , $node_i) ; my $type ; if ( $node_i->key eq 'nl' ) { $type = 'numbered' ;} elsif ( $node_i->key eq 'ul' ) { $type = 'unnumbered' ;} elsif ( $node_i->key eq 'pl' ) { $type = 'plain' ;} my $set_root = 1 if $new_xml->base->null ; $new_xml->{list}{type} = $type ; $new_xml = $new_xml->{list} if $set_root ; push( @{$new_xml->{'list-item'}} , @lines) ; process($node_i , $new_xml->{listitem} ) ; } }