in reply to xml file reading and displaying

I would go for the twig_handlers approach. Here is something I knocked together very quickly. Note you have a missing '</list>' closing element in your XML. It doesn't produce quite the same output but I am sure you can tailor it for your own purposes.
use strict; use XML::Twig; use subs qw(say); my $twig = XML::Twig->new( twig_handlers => { head => \&head, para => \&para, } )->parsefile("foo.xml"); exit; sub head { my ($t, $e) = @_; say '<h3>'.$e->text.'</h3>'; } sub para { my ($t, $e) = @_; process_children($t, $e); } sub list { my ($t, $e) = @_; say '<ol>'; process_children($t, $e); say '</ol>'; } sub item { my ($t, $e) = @_; say '<li>'.$e->text.'</li>'; } sub process_children { my ($t, $e) = @_; map { if ($_->is_text()) { say $_->text; } else { &{\&{$_->gi}}($t, $_) if exists &{$_->gi}; } } $e->children(); } sub say { return print 'TX ', @_, "\n"; }