Hi,
I need to sort the children of the "Entries" element using the "a" attribute with XML::Twig but cannot find a method to do so. The structure is as follows:
<Entries>
<datatag1 a="A1">
<t>A</t>
</datatag1>
<datatag1 a="ABA1">
<t>D</t>
</datatag1>
<datatag1 a="C1">
<t>1</t>
</datatag1>
<datatag1 a="F1">
<t>14</t>
</datatag1>
<datatag1 a="AB1">
<t>1</t>
</datatag1>
</Entries>
The desired order after sorting needs to be:
<Entries>
<datatag1 a="A1">
<t>A</t>
</datatag1>
<datatag1 a="C1">
<t>1</t>
</datatag1>
<datatag1 a="F1">
<t>14</t>
</datatag1>
<datatag1 a="AB1">
<t>1</t>
</datatag1>
<datatag1 a="ABA1">
<t>D</t>
</datatag1>
</Entries>
However the alphabetical sorting using:
$root->sort_children_on_att('a');
does not give the desired results. This is expected as alphabetically AB follows A. Is there any other way to do the sorting with XML::Twig to get the desired result?
Any help much appreciated.
Twig's sorting methods don't accepts a custom sort method, but you can always use Perl's sort and cut/paste the nodes:
#!/usr/bin/perl
use warnings;
use strict;
use XML::Twig;
my $xml = '<Entries>...</Entries>';
sub sort_children {
my $parent = $_;
my @children = sort {
length $a->att('a') <=> length $b->att('a')
or $a->att('a') cmp $b->att('a')
} $parent->cut_children;
$_->paste(last_child => $parent) for @children;
}
my $twig = 'XML::Twig'->new(twig_handlers => { Entries => \&sort_children });
$twig->parse($xml);
$twig->print;