in reply to XML::Twig handling arrays

The big problem with XML::Simple (which the simplify method in XML::Twig emulates) is how to specify what should end up as an array and what should end up as a hash in the resulting structure.

In you case it seems that you want only NativeNightlyRates and DisplayNightlyRates as arrays, the rest of the data should be stored as hashes. You can get just that by, instead of forcing everything as an array with forcearray => 1, being more selective and writing forcearray => [ qw(NativeNightlyRates DisplayNightlyRates) ].

The resulting structure is:

$VAR1 = { 'nativeCurrencyCode' => 'USD', 'displayCurrencyCode' => 'USD', 'chargeableRoomRateTaxesAndFees' => '159.77', 'rateFrequency' => 'B', 'chargeableRoomRateTotal' => '1106.62', 'NativeNightlyRates' => { 'nativeNightlyRate' => [ '298.95', '298.95', '348.95' ], 'size' => '3' }, 'DisplayNightlyRates' => { 'size' => '3', 'displayNightlyRate' => [ '298.95', '298.95', '348.95' ] }, 'displayRoomRate' => '1106.62', 'nativeRoomRate' => '1106.62' };

I am not sure that is exactly what you need to use with HTML::Template, which would seem to require arrays of hashes in NativeNightlyRates and DisplayNightlyRates. You could do this by processing either the data structure returned by simplify, or by working directly on the twig, before applying simplify. I would work on the twig, but you might have guessed that ;--)

First I would turn the text content of the nativeNightlyRate and displayNightlyRate elements into an attribute, so you can get an array of hashes, then I would erase the DisplayNightlyRates/NativeNightlyRates layer, as it just makes it harder to access the data without helping much (the size attribute can be discarded, it's just the size of the array):

#!/usr/bin/perl -w use strict; use Data::Dumper; use XML::Twig; my $twig= XML::Twig->new( twig_handlers => { nativeNightlyRate => su +b { content_to_att($_, 'rate'); }, displayNightlyRate => su +b { content_to_att($_, 'rate'); }, DisplayNightlyRates => su +b { $_->erase }, NativeNightlyRates => su +b { $_->erase }, } ); my $xml=qq~<RateInfo> <displayCurrencyCode>USD</displayCurrencyCode> <DisplayNightlyRates size=\'3\'> <displayNightlyRate>298.95</displayNightlyRate> <displayNightlyRate>298.95</displayNightlyRate> <displayNightlyRate>348.95</displayNightlyRate> </DisplayNightlyRates> <displayRoomRate>1106.62</displayRoomRate> <chargeableRoomRateTotal>1106.62</chargeableRoomRateTotal> <chargeableRoomRateTaxesAndFees>159.77</chargeableRoomRateTaxe +sAndFees> <nativeCurrencyCode>USD</nativeCurrencyCode> <NativeNightlyRates size=\'3\'> <nativeNightlyRate>298.95</nativeNightlyRate> <nativeNightlyRate>298.95</nativeNightlyRate> <nativeNightlyRate>348.95</nativeNightlyRate> </NativeNightlyRates> <nativeRoomRate>1106.62</nativeRoomRate> <rateFrequency>B</rateFrequency> </RateInfo>~; $twig->parse( $xml); # build the twig my $struct = $twig->simplify( forcearray => [ qw(NativeNightlyRate DisplayNightlyRate) ], ); print Dumper $struct; sub content_to_att { my( $elt, $att)= @_; $elt->set_att( $att => $elt->text)->cut_children; }

This outputs:

$VAR1 = { 'nativeCurrencyCode' => 'USD', 'displayCurrencyCode' => 'USD', 'chargeableRoomRateTaxesAndFees' => '159.77', 'rateFrequency' => 'B', 'chargeableRoomRateTotal' => '1106.62', 'displayNightlyRate' => [ { 'rate' => '298.95' }, { 'rate' => '298.95' }, { 'rate' => '348.95' } ], 'nativeNightlyRate' => [ { 'rate' => '298.95' }, { 'rate' => '298.95' }, { 'rate' => '348.95' } ], 'displayRoomRate' => '1106.62', 'nativeRoomRate' => '1106.62' };

Is this what you were looking for?