dalgetty has asked for the wisdom of the Perl Monks concerning the following question:

Dear Brethren of the Order,

My module takes a chunk of three level simple XML from XML::Simple with $xml=XMLin($xmlstream); and converts the resulting array/hash into a variety of formats.

The code below reads in and stores the element names and their contents. This means that no prior knowledge of the element names is necessary, so that the module can read any three level simple XML file.
sub init() { my ($self)=@_; my $source=$self->matrix; foreach my $node(keys (%$source)) { my $elem=$source->{$node}; my $count=0; foreach my $attr (@$elem) { ##### line 60 $self->print.="\n\n$node $count\n\n"; if ($count<1) {$self->nodename=$node;} foreach my $subnode(keys(%$attr)) { $self->print.=$subnode."\t".$attr->{$subnode}."\n"; } $count++; } } }
It worked beautifully until I started to test the boundaries. With huge chunks of XML it works fine, with smallish ones also, for example:
<root> <car> <make>audi</make> </car> <car> <make>sbarro</make> </car> </root>
However, if there is only one element, such as:
<root> <car> <make>audi</make> </car> </root>
Then I get this error: Not an ARRAY reference at transForm.pm line 60.

I am starting to feel a little bit out of my depth here... Can anybody help me?

Thank you, O holy ones

Dalgetty

Replies are listed 'Best First'.
Re: XML::Simple, but not for me
by Corion (Patriarch) on May 01, 2007 at 09:57 UTC

    You want to use ForceArray => [qw(make)] when constructing your XML::Simple object. Otherwise, XML::Simple will guess from the single appearance of the (only) make element that it can only appear once.

      Thanks for those wise words, Corion! I am getting my head around it now.

      I did a Data::Dump and that is indeed the problem - when there is only one element the output is a hash table within a hash table, instead of an array of hash tables within a hash table.

      Is there any way to instruct XML::Simple to make an array of hash tables within a hash table without using the name of the element?

      Up until now this module has allowed the use of arbitrarily named elements and I would like to keep it this way.

      Thanks a lot,

      dalgetty