关于设置由XMLout
. 但是,我无法使用这些答案/示例来解决问题。
我有一个脚本需要输出一些 XML 数据,并且某些元素需要按一定的顺序打印。哈希非常复杂,我无法通过覆盖对象sorted_keys
来获得任何结果。XML::Simple
嗯,我做到了,但不是我想要的方式。
示例代码如下,问题的详细信息在代码下方。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
package MyXMLSimple;
use base 'XML::Simple';
sub sorted_keys
{
my ($self, $name, $hashref) = @_;
# ...
return $self->SUPER::sorted_keys($name, $hashref);
}
package main;
my $xmlParser = MyXMLSimple->new;
my $items = {
'status' => 'OK',
'fields' => {
'i1' => {
'header' => 'Header 1',
'max_size' => '3'
},
'i2' => {
'header' => 'Header 2',
'max_size' => '8'
}
},
'item_list' => {
'GGG' => {
'index' => '3',
'i' => 3,
'points' => {
'p5' => {
'data' => '10',
}
},
},
'AAA' => {
'index' => '1',
'i' => 2,
'points' => {
'p7' => {
'data' => '22',
}
},
},
'ZZZ' => {
'index' => '2',
'i' => 1,
'points' => {
'p6' => {
'data' => '15',
}
},
}
}
};
my $xml = $xmlParser->XMLout($items);
print "$xml";
所以,这个脚本的输出将是这样的:
<opt status="OK">
<fields name="i1" header="Header 1" max_size="3" />
<fields name="i2" header="Header 2" max_size="8" />
<item_list name="AAA" i="2" index="1">
<points name="p7" data="22" />
</item_list>
<item_list name="GGG" i="3" index="3">
<points name="p5" data="10" />
</item_list>
<item_list name="ZZZ" i="1" index="2">
<points name="p6" data="15" />
</item_list>
</opt>
item_list
元素被打印出来,输出顺序是按字母顺序,通过name
属性排序。输出顺序为 AAA、GGG、ZZZ。
但是,我需要的是在对i
元素进行排序(从数字上,从最低到最高)时获得输出。因此输出将按 ZZZ、AAA、GGG 的顺序排列。
我无法控制哈希中的顺序(不是不使用Tie::...
模块),所以我不能那样做。如果我使用NoSort => 1
,输出将不会按任何特别排序,所以我最终会得到随机输出。
sorted_keys
所以,我很确定必须有一种方法可以通过覆盖子程序来按照我想要的方式进行排序。但是,我无法得到我想要的结果,因为sorted_keys
每个实例都会调用item_list
. 当sorted_keys
为opt
元素调用时,我只需访问整个哈希引用,但同样无法保证不依赖Tie::
模块的输出排序。
现在,我已经设法让它以我想要的方式工作,通过使用Tie::IxHash
模块,然后覆盖sorted_keys
和(重新)创建一个 subhash item_list
,通过将原始哈希中的值重新插入新的(有序的)一个,然后删除原始哈希中的子哈希,和用新的有序哈希替换它。
像这样的东西:
sub sorted_keys
{
my ($self, $name, $hashref) = @_;
if ($name eq "opt")
{
my $clist = { };
tie %{$clist}, "Tie::IxHash";
my @sorted_keys = sort { $hashref->{item_list}->{$a}->{i} <=> $hashref->{item_list}->{$b}->{i} } keys %{$hashref->{item_list}};
foreach my $sorted_key (@sorted_keys)
{
$clist->{$sorted_key} = $hashref->{item_list}->{$sorted_key};
}
delete $hashref->{item_list};
$hashref->{item_list} = $clist;
}
return $self->SUPER::sorted_keys($name, $hashref);
}
尽管这可行(到目前为止似乎工作可靠),但我确实相信必须有一种方法可以在不使用Tie::IxHash
模块和进行所有哈希重新排序/重新排序的情况下实现这一点,并且只能通过某种方式从内部排序/返回某些数据sorted_keys
。
我只是想不通,而且我真的不明白sorted_keys
应该如何工作(尤其是当您使用不同/复杂的输入数据集得到不同的结果时;),但我希望有人知道这一点.
我的意思是,我已经尝试XML/Simple.pm
在子程序的最后一个返回行中修改自身并更改排序顺序sorted_keys
,但我仍然得到按字母数字排序的输出。恐怕我无法弄清楚如何修改它,因此它不会排序,name
而是排序i
。