Как мне сохранить порядок значений в XML-файле, когда я читаю его с помощью XML :: Simple? - PullRequest
0 голосов
/ 13 сентября 2010

Я использую XML :: Simple для анализа XML-файла.Код приведен ниже с XML-файлом,

use Tie::IxHash;

tie %$data, "Tie::IxHash";

use XML::Simple;
use Data::Dumper;

$xml = new XML::Simple;
$data = $xml->XMLin("ship_order.xml");
print Dumper($data);

XML-файлом, (ship_order.xml)

<?xml version="1.0" encoding="UTF-8" ?> 

<shipment>
    <shiptoaddress>
        <name>Prasad</name> 
        <address>AnnaNagar</address> 
    </shiptoaddress> 
    <items>
        <quantity>5</quantity> 
        <price>100</price> 
    </items> 
    <items>
        <quantity>6</quantity> 
        <price>50</price> 
    </items>
    <num_of_items>2</num_of_items>
</shipment>

Вывод идет не по порядку, хотя я использую Tie :: IxHashмодуль.

Мой вывод:

$VAR1 = {
          'num_of_items' => '2',
          'shiptoaddress' => {
                             'name' => 'Prasad',
                             'address' => 'AnnaNagar'
                           },
          'items' => [
                     {
                       'quantity' => '5',
                       'price' => '100'
                     },
                     {
                       'quantity' => '6',
                       'price' => '50'
                     }
                   ]
        };

Ответы [ 2 ]

6 голосов
/ 13 сентября 2010

Ах, но вы не используете Tie::IxHash.Точнее, вы начинаете с использования Tie::IxHash, а затем уничтожаете его:

$data = $xml->XMLin("ship_order.xml");

Эта строка отбрасывает созданную вами ссылку на хэш и присваивает ее из вызова метода для $data.

Если вы заботитесь о порядке элементов (и вам, вероятно, не нужно это делать, поскольку любой приличный формат XML будет содержать атрибут, сообщающий вам порядок), вам нужно будет использовать синтаксический анализатор, который возвращаетобъект, а не структура данных.Объект будет знать порядок просмотра элементов и предоставит вам метод children, который их возвращает.

В качестве альтернативы, вы можете построить структуру данных самостоятельно:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $shipment;
my $t = XML::Twig->new(
    twig_handlers => {
        shiptoaddress => sub {
            my ($t, $elt) = @_;

            $shipment->{name}    = $elt->first_child("name")->text;
            $shipment->{address} = $elt->first_child("address")->text;

            $t->purge;
        },
        items => sub {
            my ($t, $elt) = @_;

            push @{$shipment->{items}}, {
                quantity => $elt->first_child("quantity")->text,
                price    => $elt->first_child("price")->text,
            };

            $t->purge;
        },
    },
);

$t->parse(join "", <DATA>); #FIXME: use parsefile later

use Data::Dumper;
print Dumper $shipment;

__DATA__
<?xml version="1.0" encoding="UTF-8" ?> 

<shipment>
    <shiptoaddress>
        <name>Prasad</name> 
        <address>AnnaNagar</address> 
    </shiptoaddress> 
    <items>
        <quantity>5</quantity> 
        <price>100</price> 
    </items> 
    <items>
        <quantity>6</quantity> 
        <price>50</price> 
    </items>
    <num_of_items>2</num_of_items>
</shipment>
3 голосов
/ 13 сентября 2010

Можно рассмотреть создание подкласса XML::Simple и перезаписать необходимый метод, который создает хэш с Tie::IxHash.

Однако всерьез рассмотрим ответ, данный автором XML::Simple на форуме CPAN в этой теме: как сохранить порядок элементов XML :: Simple ...

Сохранение порядка элементов не является и никогда не будет функцией XML :: Simple. Для некоторых типов документов XML вы можете взломать его, создав подкласс XML :: Simple и переопределив метод new_hashref () для предоставления хэш-ссылки, связанной с Tie :: IxHash. Это может решить дело ABC, но это не решит дело ABA. Короткий ответ: если вы заботитесь о порядке элементов, вам не следует использовать XML :: Simple. XML :: LibXML - отличная альтернатива, которую для многих случаев использования на самом деле не сложнее, чем XML :: Simple - как описано в [1]

А также то, что он вставил в код :

##############################################################################
# Method: new_hashref()
#
# This is a hook routine for overriding in a sub-class.  Some people believe
# that using Tie::IxHash here will solve order-loss problems.
# 

sub new_hashref {
  my $self = shift;

  return { @_ };
}

[1] - Переход от XML :: Простой к XML :: LibXML

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...