First of all, please don't use XML::Simple
. Its own documentation says this
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.
You should also check the result of any subroutine call or shell command using Data::Dump
. It would look like this
perl -MData::Dump -E'dd `hostname`'
which on my system shows
"Samurai-U\n"
Hopefully you now see the problem? The string returned by the backticks has a trailing newline character, and there is element in your $xmlObject
hash that has a key like that. You can fix it with
chomp(my $host = `hostname`)
after which you could write
my %systemHash = %{ $xmlObject->{SERVER}{$host} }
Finally, it is wasteful to copy all of the first level of a hash as you do here
my %systemHash = %{$xmlObject->{SERVER}->{`hostname`}}
You don't go on to show what you want to use this information for, but in general it is far better to extract a hash reference, using
chomp( my $hostname = `hostname` );
my $systemHash = $xmlObject->{SERVER}{$hostname};
Update
It would be very much better to use a proper XML-parsing module.
Here is an example solution using XML::LibXML
use strict;
use warnings;
use 5.010; # For 'say'
use XML::LibXML;
my ($xml_file) = @ARGV;
my $xml = XML::LibXML->load_xml(location => $xml_file);
my @servers = $xml->findnodes('/main/server');
my @server_names = map $_->findvalue('@hostname'), @servers;
say "- $_" for @server_names;
input file
<main>
<server hostname="server1" more_attributes="more"/>
<server hostname="server2" more_attributes="more"/>
<server hostname="server3" more_attributes="more"/>
</main>
output
- server1
- server2
- server3