http://www.perlmonks.org?node_id=337131

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

I'm trying to learn how to manipulate XML using Perl. I got this code off a website, but it isn't working.
use strict; use XML::Simple; my $file = 'files/camelids.xml'; my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin($file); foreach my $key (keys (%{$doc->{species}})){ print $doc->{species}->{$key}->{'common-name'} . ' (' . $key . ') ' +; print $doc->{species}->{$key}->{conservation}->{status} . "\n"; }
This is the file it's accessing...
<?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 ... </appearance> </physical-characteristics> <natural-history> <food-habits> Camels are herbivores... </food-habits> <reproduction> Mating season occurs ... </reproduction> <behavior> Domestic camels ... </behavior> <habitat> The camel's habitat ... </habitat> </natural-history> <conservation status="endangered"> <detail> Camels were thought ... </detail> </conservation> </species> </camelids>
Can anyone tell me what's wrong with it, or give me some kind of guidance on how to manipulate XML in Perl.

Sorry, by not working, I meant that it's totally and completely not working. I'm getting a "500 Internal Server Error" error.

Replies are listed 'Best First'.
Re: Perl and XML
by jeffa (Bishop) on Mar 16, 2004 at 23:08 UTC
    To elaborate on what bart said, you have to print out a Content Header if you want to view this as a web page from a browser. One easy way is to use CGI.pm:
    use strict; use XML::Simple; use CGI qw(header); print header('text/plain'); my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin('files/camelids.xml'); foreach my $key (keys (%{$doc->{species}})){ print $doc->{species}->{$key}->{'common-name'} . " ($key) "; print $doc->{species}->{$key}->{conservation}->{status} . "\n"; }
    You also have to make sure that the CGI file is executable by everyone ... "chmod 755 foo.cgi" should do the trick if you have command line access.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      thank you - got it, that was the problem
Re: Perl and XML
by chip (Curate) on Mar 16, 2004 at 21:30 UTC
    When in doubt of a dada structure, use Data::Dumper, YAML, or the debugger's "x" command to see what it actually is. Then figuring out how to access it should be child's play.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Perl and XML
by bart (Canon) on Mar 16, 2004 at 22:54 UTC
    I'm getting a "500 Internal Server Error" error.
    Duh? You're running this as a CGI script? So where do you print out the header(s), and the blank line?

    Your syntax is fine, I don't have a sample of your XML file, and thus I'm not convinced that's not all there is to it.

      what do you mean by header and blank line?
      #!/usr/bin/perl
      these things?
        No, you need that too, and it must be a proper path to perl too, but that's usually called the shebang line.

        No, I'm now talking about CGI 101, you can use a simple

        print "Content-type: text/plain\n\n";
        before your print anything else, or something similar but more advanced from one of the CGI modules.

        For simple experimentation, it'd be best to use something like

        use CGI::Carp 'fatalsToBrowser';
        because then you'll get your Perl error messages in the browser window, too.
Re: Perl and XML
by matija (Priest) on Mar 16, 2004 at 21:28 UTC
    First, I think you will need to access $doc->{camelids}{species}...etc... - the camelids needs to be explicitly there.

    Second, I warmly recommend you use XML::Smart.

    I've used both XML::Simple and XML::Smart, and working with Smart is much, much easier for me.

      - the camelids needs to be explicitly there.

      No, with the default options the original script uses, the top level element will be discarded.

Re: Perl and XML
by Anonymous Monk on Mar 16, 2004 at 22:56 UTC
    I played with XML::Simple a little and found out that it is really good for very simple things. If you are having trouble doing something that is less than simple you might try using XML::LibXML. LibXML is harder to get your head around as a beginner but it works really well.