in reply to Re: XML::Simple Multi-Layered
in thread XML::Simple Multi-Layered

I guess I am looking for a more general way to get data further into the tree. This is most of an example from perl-xml-quickstart:
<?xml version="1.0"?> <camelids> <species name="Camelus bactrianus"> <common-name>Bactrian Camel</common-name> <physical-characteristics> <mass>450 to 500 kg.</mass> <appearance> The most noticeable feature of C. bactrianus is its two humps. </appearance> </physical-characteristics> <natural-history> <food-habits> Camels are herbivores. </food-habits> <reproduction> Mating season occurs in the fall, with inbreeding often invol +ved in domesticated camels. </reproduction> <behavior> Domestic camels travel in caravans across the desert. </behavior> <habitat> The camel's habitat consists mainly of Asia's deserts. </habitat> </natural-history> <conservation status="endangered"> <detail> Camels were thought to be extinct in the wild. </detail> </conservation> </species> <species name="Camelus dromedarius"> <common-name>Dromedary, or Arabian Camel</common-name> <physical-characteristics> <mass>300 to 690 kg.</mass> <appearance> The dromedary camel is characterized by a long-curved neck, de +ep-narrow chest, and a single hump. </appearance> </physical-characteristics> <natural-history> <food-habits> The dromedary camel is a herbivore. </food-habits> <reproduction> The dromedary camel has a lifespan of about 40-50 years. </reproduction> <behavior> With the exception of rutting males, dromedaries show very li +ttle aggressive behavior. </behavior> <habitat> The camels prefer desert conditions characterized by a long d +ry season and a short rainy season. </habitat> </natural-history> <conservation status="no special status"> <detail> Since the dromedary camel is domesticated, the camel has no sp +ecial status in conservation (Busch Gardens 1996). </detail> </conservation> </species> <species name="Lama glama"> <common-name>Llama</common-name> <physical-characteristics> <mass>130 to 155 kg.</mass> <appearance> Llamas feet are slender and their limbs are long. </appearance> </physical-characteristics> <natural-history> <food-habits> Llamas are herbivorous, feeding on many kinds of grasses and +leaves. </food-habits> <reproduction> Llamas reach sexual maturity at about 12-24 months. </reproduction> <behavior> The Lama glama lives only in domestication. </behavior> <habitat> Llamas are found in deserts, mountainous areas, and grassland +s. </habitat> </natural-history> <conservation status="no special status"> <detail> The population of llamas has declined since road building redu +ced their importance in transportation. </detail> </conservation> </species> <species name="Lama guanicoe"> <common-name>Guanaco</common-name> <physical-characteristics> <mass>115 to 140 kg.</mass> <appearance> They stand at 1,100 to 1,200mm at the shoulder and have slende +r bodies with long limbs and neck. </appearance> </physical-characteristics> <natural-history> <food-habits> Guanacos are herbivores that can inhabit dry areas and forego + drinking for long periods. </food-habits> <reproduction> Females are apparently induced ovulators. </reproduction> <behavior> There are three types of social groups: family groups, male t +roops, and solitary males. </behavior> <habitat> Guanacos inhabit grasslands and shrublands from sea level to +4,000m. Occasionally they winter in forests. </habitat> </natural-history> <conservation status="special concern"> <detail> Guanacos have had their numbers drastically reduced due to hum +an pressures of habitat encroachment, habitat destruction, and hunting. </detail> </conservation> </species> <species name="Vicugna vicugna"> <common-name>Vicuna</common-name> <physical-characteristics> <mass>35 to 65 kg.</mass> <appearance> The vicuna is the smallest living species among the family Cam +elidae. </appearance> </physical-characteristics> <natural-history> <food-habits> The vicuna is strictly a grazer. </food-habits> <reproduction> Mating begins in March and April. </reproduction> <behavior> Vicunas are alert and shy animals that flee very rapidly. </behavior> <habitat> Vicunas are found in semiarid rolling grasslands and plains at + altitudes of 3,500-5,750 meters. </habitat> </natural-history> <conservation status="endangered"> <detail> The vicuna is classified as vulnerable by the IUCN, and as end +angered by the USDI. </detail> </conservation> </species> </camelids>
Some code to pull data from the XML:
#!/usr/bin/perl use strict; use XML::Simple; my $file = 'files/camelids.xml'; my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin($file, forcearray => 1); foreach my $key (keys (%{$doc->{species}})){ print $doc->{species}->{$key}->{'common-name'}[0]; print " ($key) "; print "\n"; }
I can get data from the species key and the common-name (one level in) but how do you get, say, the physical-characteristics->mass? things like:
print $doc->{species}->{$key}->{'physical-characteristics'}[0];
and
print $doc->{species}->{$key}->{'physical-characteristics'}['mass'];
only give the hashref. Do I need another foreach loop? Thanks

Replies are listed 'Best First'.
Re^3: XML::Simple Multi-Layered
by wfsp (Abbot) on Aug 16, 2007 at 17:38 UTC
    Nearly, in both cases :-)
    print $doc->{species}{$key}{'physical-characteristics'}[0]{mass}[0] # and print $doc->{species}{$key}{'physical-characteristics'}[0]{appearance} +[0]
    The square brackets indicate array refs so you need an element index (a number). So ['mass'] won't work.
      Thank you, that works. However, now I am still having issues with my original XML above. Using:
      my $doc = $xs1->XMLin($file, forcearray => 1, keyattr => {client_syste +m => 'Customer Care'});
      then Data::Dumper gives me output like this:
      $VAR1 = { 'client_system' => [ { 'business_area' => [ { 'component' => [ { 'component_lib' => [ { 'class_set' => [ { 'data_type' => '1', 'linked_characteristic_name' => '4-MTH-AV +G-UTIL', 'version' => '2.0', 'name' => 'Active Strategy 2', 'is_protected' => 'false', 'base_class_set' => [ { 'interval' => [ { 'outcome' => [ { 'uniqueID' => '2', 'displayPosition' => '1', 'name' => 'low-199' } ], 'is_Others' => ['false'], 'range' => ['low-199'], 'name' => 'low-199' + + + }, + + { + + 'outcome' => [ + + + { + + 'uniqueID' => '3', + + + 'displayPosition' => '2', + + + 'name' => '200-499' } ], 'is_Others' => ['false'], 'range' => ['200-499'], 'name' => '200-499' }, { 'outcome' => [ { 'uniqueID' => '4', 'displayPosition' => '3' +, 'name' => '500-899' } ], 'is_Others' => ['false'], 'range' => ['500-899'], 'name' => '500-899' }, { 'outcome' => [ { 'uniqueID' => '1', 'displayPosition' => +'2147483647', 'name' => 'Others' } ], 'is_Others' => ['true'], 'name' => 'Others' } ] } ], 'obj_info' => [ { 'obj_revision' => '1', 'version' => '2.0', 'name' => 'CS A1524 CD GM Active Strategy +2', 'library_unique_id' => '00000071', } ] } ], 'type' => 'class_set' } ] } ], 'name' => 'GM Business Area', 'analytics' => [ {} ] } ], . . .
      Sorry for the mess but I'm tired of formatting. Anyway, I basically want to get all of the interval=>names for the business_area client_system and I have:
      my $doc = $xs1->XMLin($file, forcearray => 1, keyattr => {client_syste +m => 'Customer Care'}); foreach my $key (keys (%{$doc->{client_system}})){ if($key eq 'business_area') { print $doc->{client_system}[$key]->{component}[0]->{component_ +lib}[0]->{class_set}[0]->{base_class_set[0]->{interval}{'range'}, "\n +"; } }
      or something like that. Just confused with the syntax on the print command. Probably also have to loop through again to get all the interval names. Thanks in advance
        For the sake of example I've stripped down the data to just leave the bits we're looking at. (note the $Data::Dumper::Indent = 1; line, it compacts Dumper's output a bit).

        You have a series of nested hash of arrays (HoAs).

        Here I've extracted the array ref we want and looped over it.

        output:

        low-199 200-499 500-899 Others

        fwiw
        I find that setting tabs to spaces with a tab setting of 2 can help make code a bit more readable