Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

parsing complex xml structure with xml::simple

by bfdi533 (Friar)
on Aug 01, 2006 at 14:21 UTC ( #564998=perlquestion: print w/replies, xml ) Need Help??

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

I have an xml input file that I need to parse and the structure is pretty complex. I have been working my way through the structure fairly well but have run into a situation that I do not know how to handle. I am using code to dereference parts of the xml structure to more easily deal with them.

One part is throwing me though. I have a set that is a Row(s) of Detail info that can either contain a hash or an array of hashes. I had been dealing with this as an array of hashes but when it gets to a single hash rather than an array the code crashes with an "Not an ARRAY reference at ..." error.

Here is the code:

if ($checks->{Detail}) { foreach my $detail (@{$checks->{Detail}->{Row}}) { foreach my $col (@{$detail->{Col}}) { print "$col \n"; } } }
And here is a piece of the data:
<Check> <Detail> <Head> <Col>User</Col> <Col>Weak Password</Col> <Col>Locked Out</Col> <Col>Disabled</Col> </Head> <Row Grade="0"> <Col>Guest</Col> <Col>Weak</Col> <Col>-</Col> <Col>Disabled</Col> </Row> <Row Grade="0"> <Col>SUPPORT_388945a0</Col> <Col>-</Col> <Col>-</Col> <Col>Disabled</Col> </Row> <Row Grade="5"> <Col>Administrator</Col> <Col>-</Col> <Col>-</Col> <Col>-</Col> </Row> </Detail> </Check> <Check> <Detail> <Head> <Col>Drive Letter</Col> <Col>File System</Col> </Head> <Row Grade="5"> <Col>C:</Col> <Col>NTFS</Col> </Row> </Detail> </Check>

How can I go about handling the multiple rows versus the single row situation with efficient code?

Is there a way to check to see if a variable is an array a has and execute an if/then/else code segment?

Replies are listed 'Best First'.
Re: parsing complex xml structure with xml::simple
by davorg (Chancellor) on Aug 01, 2006 at 14:25 UTC

    You can use ref to find out what kind of reference a scalar holds.

    But I strongly suspect that what you really need here is XML::Simple's ForceArray option.


    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: parsing complex xml structure with xml::simple
by ptum (Priest) on Aug 01, 2006 at 14:26 UTC

    Happily, there is: ref will help you to identify an array reference. You could do something like this:

    if (ref($detail->{Col}) eq 'ARRAY') { # do something } else { # do something else }

    Update: Hmmph. I get up at 4:40 am and davorg still beat me to this answer, darn those timezone-advantaged monks! Plus, his answer is better. That ForceArray solution looks cool.

    No good deed goes unpunished. -- (attributed to) Oscar Wilde

      This is a good solution. I know that for the most part that most of the items will NOT be contained in arrays so for the ones that I know about, this seems like just the ticket!


Re: parsing complex xml structure with xml::simple
by GrandFather (Sage) on Aug 01, 2006 at 18:50 UTC

    You may find XML::TreeBuilder easier to deal with than XML::Simple for non-trivial XML:

    use strict; use warnings; use XML::TreeBuilder; my $xmlStr = <<'STR';
    STR my $tree = XML::TreeBuilder->new; $tree->parse ($xmlStr); for ($tree->find ('Detail')) { for ($_->find ('Row')) { print "Col: " . $_->as_text () . "\n" for ($_->find ('Col')); } }


    Col: Guest Col: Weak Col: - Col: Disabled Col: SUPPORT_388945a0 Col: - Col: - Col: Disabled Col: Administrator Col: - Col: - Col: - Col: C: Col: NTFS

    DWIM is Perl's answer to Gödel
Re: parsing complex xml structure with xml::simple
by planetscape (Chancellor) on Aug 02, 2006 at 18:04 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://564998]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2019-12-06 12:49 GMT
Find Nodes?
    Voting Booth?
    Strict and warnings: which comes first?

    Results (155 votes). Check out past polls.