XML Simple force array

B

-Brad-

Hi all,

I have an xml file that looks like :

<control_file name="XXXX_99.ctl">
<files_ps count="2">
<file seq="1" name="file1.gz" size="1107045" />
<file seq="2" name="file2.gz" size="1107045" />
</files_ps>
</control_file>

I would like to be able to loop through all the child elements under
files_ps, and print out their attribute values.
I was planning on using forcearray on the 'file' node so I can loop through
all the array elements, but I cant seem to get it to work.

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

my $xs = new XML::Simple();
my $xml = $xs->XMLin(<->,
keeproot => '1',
forcearray=> ['file',]
);

print Dumper($xml); # it still looks like a hash, not an array!


Any help would be apprecitaed!

Cheers
 
M

Marc Lucksch

-Brad- said:
Hi all,

I have an xml file that looks like :

<control_file name="XXXX_99.ctl">
<files_ps count="2">
<file seq="1" name="file1.gz" size="1107045" />
<file seq="2" name="file2.gz" size="1107045" />
</files_ps>
</control_file>

I would like to be able to loop through all the child elements under
files_ps, and print out their attribute values.
I was planning on using forcearray on the 'file' node so I can loop through
all the array elements, but I cant seem to get it to work.
That is because XML::Simple treats the name special and as a unique
identifier, you will have to switch that off:

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

my $xs = new XML::Simple();
my $xml = $xs->XMLin("test.xml",
KeyAttr => [],
keeproot => '1',
forcearray=> ['file',]
);

print Dumper($xml);
__END__

$VAR1 = {
'control_file' => {
'name' => 'XXXX_99.ctl',
'files_ps' => {
'count' => '2',
'file' => [
{
'name' => 'file1.gz',
'seq' => '1',
'size' => '1107045'
},
{
'name' => 'file2.gz',
'seq' => '2',
'size' => '1107045'
}
]
}
}
};

On the other hand, if name is unique you could also use foreach keys to
iterate.

Marc "Maluku" Lucksch
 
M

Marc Lucksch

Christian said:
-Brad- wrote:
"forcearray" ne "ForceArray". Yes
Perl is case sensitive.
Nope, that ain't it, XML::Simple doesn't care.

Marc "Maluku" Lucksch
 
X

xhoster

-Brad- said:
Hi all,

I have an xml file that looks like :

<control_file name="XXXX_99.ctl">
<files_ps count="2">
<file seq="1" name="file1.gz" size="1107045" />
<file seq="2" name="file2.gz" size="1107045" />
</files_ps>
</control_file>

I would like to be able to loop through all the child elements under
files_ps, and print out their attribute values.
I was planning on using forcearray on the 'file' node so I can loop
through all the array elements, but I cant seem to get it to work.

ForceArray only has an effect when there is exactly one element. If there
is more than one element (like your 'file') then it is already put into
an array. If less than one, there is nothing there in the first place.

But after it is put into an array, the action of KeyAttr might re-arrange
it into a hash. The default value for KeyAttr is ['name', 'key', 'id'],
and since all of your "file" elements have a attribute named 'name', it
gets rearranged into a hash using 'name' as the key.

So what you need to do is add KeyAttr=>undef.

Your current example doesn't need the ForceArray, but if you every expect
to get a file_ps that has only one file, then you should keep the
ForceArray as well.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
B

-Brad-

Hi all,

Thanks you very much for your help,
Usging KeyAttr => [], has now given me an array!!!

Cheers

-Brad- said:
Hi all,

I have an xml file that looks like :

<control_file name="XXXX_99.ctl">
<files_ps count="2">
<file seq="1" name="file1.gz" size="1107045" />
<file seq="2" name="file2.gz" size="1107045" />
</files_ps>
</control_file>

I would like to be able to loop through all the child elements under
files_ps, and print out their attribute values.
I was planning on using forcearray on the 'file' node so I can loop
through all the array elements, but I cant seem to get it to work.

ForceArray only has an effect when there is exactly one element. If there
is more than one element (like your 'file') then it is already put into
an array. If less than one, there is nothing there in the first place.

But after it is put into an array, the action of KeyAttr might re-arrange
it into a hash. The default value for KeyAttr is ['name', 'key', 'id'],
and since all of your "file" elements have a attribute named 'name', it
gets rearranged into a hash using 'name' as the key.

So what you need to do is add KeyAttr=>undef.

Your current example doesn't need the ForceArray, but if you every expect
to get a file_ps that has only one file, then you should keep the
ForceArray as well.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top