in reply to Parsing XML w/ Attributes

Proud or not, post what you've got so that you're not just asking us to do your work for you. A couple of tips would be to make sure you've read the doc on XML::Simple, especially pertaining to the ForceArray option.

Replies are listed 'Best First'.
Re^2: Parsing XML w/ Attributes
by jpk236 (Monk) on Dec 19, 2007 at 20:47 UTC
    Fair enough :-P

    Between posting and now I've come up with the following code which seems to work:
    #!/usr/bin/perl -w use strict; use XML::Simple; my ($ref); $ref = XMLin('file.xml'); foreach (sort keys %{$ref->{'host1'}->{'process'}}) { print "proc: $_\n"; }

    Is this the best way to be doing this?

    - Justin
      I would encourage you to use ForceArray. Even if it's not necessary here, down the road you'll almost certainly be glad you started out using it. This is how I would go about what you're doing, using ForceArray.
      #!/usr/bin/perl -w use strict; use XML::Simple; my $parser = new XML::Simple(ForceArray => 1); my $ref = $parser->XMLin('c:\temp\file.xml'); foreach my $host (keys(%$ref)){ foreach my $proc (keys(%{$ref->{$host}[0]->{process}})){ print "$proc is running on $host\n"; } }

        I think it's safe to assume each host is there just once so it may be better to use ForceArray => ['process'] Which will somewhat simplify the code:

        #!/usr/bin/perl -w use strict; use XML::Simple; my $parser = new XML::Simple(ForceArray => ['process']); my $ref = $parser->XMLin('c:\temp\file.xml'); foreach my $host (keys(%$ref)){ foreach my $proc (keys(%{$ref->{$host}->{process}})){ print "$proc is running on $host\n"; } }
        Also it may be better to use each() instead of foreach():
        #!/usr/bin/perl -w use strict; use XML::Simple; my $parser = new XML::Simple(ForceArray => ['process']); my $ref = $parser->XMLin('c:\temp\file.xml'); while (my ($host, $processes) = each %$ref){ foreach my $proc (keys(%{$processes->{process}})){ print "$proc is running on $host\n"; } }
        Or using a different module:
        use XML::Rules; my $parser = XML::Rules->new( rules => { process => sub { '@list' => $_[1]->{name}}, _default => sub { $_[0] => $_[1]->{list}}, config => 'pass no content', } ); my $data = $parser->parse(\*DATA); #use Data::Dumper; #print Dumper($data); foreach my $host (sort keys %$data) { foreach my $proc (@{$data->{$host}}) { print "$host runs $proc\n"; } } __DATA__ <?xml version="1.0" encoding="utf-8"?> <config> ...