After I've written a couple of classes inherited from XML::Simple, that
override only the sorted_keys() method (because sometimes the order of
tags matters), I've figured out an easy and generic way of doing that.
It'd be nice to see it in XML::Simple itself, it seems to be quite in
line with the way other options work.
It can be described as
=head2 SortMap => { list } I<# out - handy>
This option allows to specify the order of tags in the XML, as generated
by C<XMLout()>. The value of this option is a hash, the keys of which
specify in what elements the special order will be used, and the value -
another hash - maps child element names for sorting purposes. For
example, the option SortMap => { list => { attr => 'zzz' } }' when used
with this data structure:
{
attr => [ 10 ],
list => [
{ uid => [1], attr => ['a'] },
]
}
will generate this XML:
<opt>
<attr>10</attr>
<list>
<uid>1</uid>
<attr>a</attr>
</list>
</opt>
note, that <attr> under <list> was sorted B<last>, while <attr> under
<opt> was sorted B<first>. This happened because <attr>, was sorted
alphabetically in <opt>, but was sorted as <zzz> inside <list>.
=cut
and the (simplified) implementation can be
sub sorted_keys {
my ($self, $name, $hashref) = @_;
return sort keys %$hashref unless $self->{SortMap};
return sort keys %$hashref unless $self->{SortMap}->{$name};
my $map=$self->{SortMap}->{$name};
sub key($) { exists $map->{$_[0]} ? $map->{$_[0]} : $_[0] }
return sort { key($a) cmp key($b) } keys %$hashref
}