in reply to Re: XML::Simple--dealing with a variable element
in thread XML::Simple--dealing with a variable element

rhesa: the foreach option is almost working!

The first element within <attribute> is:
  <attributes>
    <attribute category="" parser="CSVParser" />

which produces the error:
Argument "" isn't numeric in each at xmlparser.pl line 58.
  Bad index while coercing array into hash at xmlparser.pl line 58.

when using the code:

foreach my $dataschema ( values %{ $data->{dataschemas}{dataschema} } +) { while( my ($name, $value) = each %{ $dataschema->{attributes}{attrib +ute} } ){ # do something with the name and value print "\$name is: $name\n\$value is: $value\n"; } }
When I used keys in place of each, I get the print line to work, but I'm stuck in an infinite loop in the process.

This shows that I don't understand very well hashes and hash functions with respect to the while( my ($name, $value) = each %{ $dataschema->{attributes}{attribute} } ) line since this error doesn't make sense to me.

I know that I'm getting hung up on the category="" item, but that's as far as I've gone in my debug process.

Replies are listed 'Best First'.
Re^3: XML::Simple--dealing with a variable element
by rhesa (Vicar) on Jul 27, 2006 at 18:14 UTC
    Your newer data shows that you usually have an array of "attribute" nodes, while I was assuming it would be a hash. I'm forcing XML::Simple to always make an array of the "attribute" nodes, and have changed the code to accomodate that.
    use XML::Simple; $data = XMLin( \*DATA, KeepRoot => 1, ForceArray => [ qw/attribute/ ] + ); @attrs = map { $_->{category} } # We want the c +ategory value map { @{ $_->{attributes}{attribute} } } # for each attr +ibute values %{ $data->{dataschemas}{dataschema} }; # in all datasc +hemas. print "@attrs\n"; __DATA__ <dataschemas> <dataschema name="varyingName1"> <attributes> <attribute category="one" fair="no" /> </attributes> </dataschema> <dataschema name="varyingName2"> <attributes> <attribute category="" parser="CSVParser" /> <attribute category="APS" internalCategory="aps" /> <attribute category="ASC" internalCategory="asc" /> <attribute category="ASMT" internalCategory="asmt" /> <attribute category="LE" internalCategory="l&amp;e" /> <attribute category="NCO" internalCategory="nco" /> <attribute category="NEED TITLE" internalCategory="need title" + /> <attribute category="New Need ID" internalCategory="need id" / +> <attribute category="SUMMARY OF DELIVERABLES" parser="TextPars +er" extract="true" segmentation="hard" /> </attributes> </dataschema> </dataschemas>
    A version based on the foreach / while idea:
    foreach my $dataschema ( values %{ $data->{dataschemas}{dataschema} } +) { foreach my $attr ( @{ $dataschema->{attributes}{attribute} } ){ print "category is: ", $attr->{category}, "\n"; } }


      I wrapped the XML snippet with <document> tags and the error went away. Now I can't get anything to print out from within the foreach loop ...

      I tried both versions of this -- foreach and 'map' ones -- and keep getting the following error:

      junk after document element at line 24, column 0, byte 825 at C:/Perl/site/lib/XML/Parser.pm line 168

      where line 24 occurs just above __DATA__. I couldn't figure out from Parser.pm what could be happening. Do you have any suggestions? Thanks much.
        The line 24, column 0, byte 825 refers to your XML content, so there must be something wrong there.