Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

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?

Comment on parsing complex xml structure with xml::simple
Select or Download Code
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.

    --
    <http://dave.org.uk>

    "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!

      Thanks!

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')); } }

    Prints:

    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 (Canon) on Aug 02, 2006 at 18:04 UTC

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (11)
As of 2015-07-07 22:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (93 votes), past polls