Using XML :: LibXML and XPath .
use 5.014; use warnings; use XML::LibXML; my $file = 'xml'; my $dom = XML::LibXML->load_xml(location => $file); for my $child ($dom->findnodes( q{//document/*} )) { say $child->nodeName(); }
Output
TITLE PART001 PART002 PART003 PART004
or just for the case if you only need PART s
for my $part ($dom->findnodes( q{//*[contains(name(),'PART')]} )) { say $part->nodeName(); }
Output
PART001 PART002 PART003 PART004
EDIT: Using pull parsing (doesn't load all xml into memory):
use 5.014; use warnings; use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT); my $file="xml"; my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!"; while($reader->read()) { if( $reader->depth == 1 && $reader->nodeType == XML_READER_TYPE_ELEMENT ) { say $reader->name; } } TITLE PART001 PART002 PART003 PART004
EDIT2
use 5.014; use warnings; use XML::LibXML::Reader qw(XML_READER_TYPE_ELEMENT); my $file="xml"; my $reader = XML::LibXML::Reader->new(location => $file) or die "problem $!"; my $indoc; while($reader->read()) {
source share