XML :: Простой порядок вывода элементов из сложного хэша

Я уже видел несколько ответов в разных местах относительно установки порядка XML-элементов, возвращаемых 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 и (повторно) создав подхеш item_list , pm и изменение порядка сортировки в последней строке возврата подпрограммы sorted_keys , но я все еще получал вывод с буквенно-цифровой сортировкой. Боюсь, я не могу понять, как бы его изменить, чтобы сортировка происходила не по name , а по i .

6
задан double-beep 9 February 2019 в 19:02
поделиться