From the XML::Simple docs:
The use of this module in new code is discouraged. Other modules are available which provide more straightforward and consistent interfaces. In particular, XML::LibXML is highly recommended.
The major problems with this module are the large number of options and the arbitrary ways in which these options interact - often with unexpected results.
Anyway.
In your code, you are skimming over the fact that the booklist contains books which contain details. The booklist has no immediate details. Here is a short solution using XML::LibXML:
use strict; use warnings; use 5.010; use XML::LibXML;
my $dom = XML::LibXML->load_xml(IO => \*DATA) or die "Can't load";
for my $detail ($dom->findnodes('/booklist/book/detail')) {
say $detail->findvalue('./name');
}
__DATA__
<?xml version='1.0' encoding='iso-8859-1'?>
<booklist>
<book>
<detail label='label1' status='active' type='none'>
<name>book1</name>
</detail >
<detail label='label2' status='active' type='none'>
<name>book2</name>
</detail >
</book>
</booklist>
As you can see in the XPATH expression /booklist/book/detail
, we first have to look into the book before finding the details. Of course, this could be shortened to //detail
.
In general, if a data structure isn't that what it seems, you should dump it, e.g.
use Data::Dumper;
print Dumper $booklist;
This would output:
$VAR1 = {
'book' => {
'detail' => {
'book2' => {
'status' => 'active',
'type' => 'none',
'label' => 'label2'
},
'book1' => {
'status' => 'active',
'type' => 'none',
'label' => 'label1'
}
}
}
};
So for some fucked up reason, the book1
and book2
strings are now keys in a nested hash. Do yourself a favour, and stop using the most complicated XML module on CPAN, the “XML::Simple”.