Yes, it might be possible to fiddle with the settings of XML::Simple some more in order to get the output closer to what you want. However, ultimately you're going to need to do some sort of translation to get your exact goal.
Why not just do the translation with what you've been given? It would probably be possible to pull the column names from the XML, and deal with the wierd empty data being turned into a hash ref, but I leave that up to you:
use XML::Simple;
use strict;
use warnings;
my $data = do { local $/; <DATA> };
my $xml = XMLin($data);
my @formatted = map {
{
ID => $_->{c}[0],
VERSION => $_->{c}[1],
NAME => $_->{c}[2],
DESCRIPTION => ref $_->{c}[3] ? '' : $_->{c}[3],
}
} @{$xml->{table}{data}{r}};
use Data::Dump;
dd \@formatted;
__DATA__
<?xml version="1.0" ?>
<resultset>
<table name="PROFILE">
<column name="ID" type="String"/>
<column name="VERSION" type="String"/>
<column name="NAME" type="String"/>
<column name="DESCRIPTION" type="String"/>
<data>
<r><c>0</c><c>1.0</c><c>Default profile</c><c>Default profile</c></r>
<r><c>2</c><c>1.2</c><c>Custom 2</c><c></c></r>
<r><c>3</c><c>6.0</c><c>Custom 3</c><c></c></r>
<r><c>1</c><c>1.15</c><c> For Compare</c><c>The built in profile for compare.</c></r>
<r><c>4</c><c>1.3</c><c>Custom 4</c><c> </c></r>
<r><c>6</c><c>11.0</c><c>Custom 6</c><c>Please only make approved changes.</c></r>
</data>
</table>
</resultset>
outputs
[
{
DESCRIPTION => "Default profile",
ID => 0,
NAME => "Default profile",
VERSION => "1.0",
},
{ DESCRIPTION => "", ID => 2, NAME => "Custom 2", VERSION => "1.2" },
{ DESCRIPTION => "", ID => 3, NAME => "Custom 3", VERSION => "6.0" },
{
DESCRIPTION => "The built in profile for compare.",
ID => 1,
NAME => " For Compare",
VERSION => "1.15",
},
{ DESCRIPTION => "", ID => 4, NAME => "Custom 4", VERSION => "1.3" },
{
DESCRIPTION => "Please only make approved changes.",
ID => 6,
NAME => "Custom 6",
VERSION => "11.0",
},
]