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


in reply to Nested XML Question

If you don't mind a little different order then this would work:

use strict; use warnings; no warnings 'uninitialized'; use XML::Rules; my $parser = XML::Rules->new( stripspaces => 7, rules => { 'ip-address-ranges' => 'content array', 'host-group' => sub { my ($tag, $attr, $parents, $parent_data) = @_; my $name = join '.', ((map $_->{name}, @{$parent_data}[1.. +$#$parent_data]), $attr->{name}); if ($attr->{'ip-address-ranges'} && @{$attr->{'ip-address- +ranges'}}) { foreach my $ip (@{$attr->{'ip-address-ranges'}}) { print "$name\t$ip\n"; } } else { print "$name\n"; } return; } }); $parser->parse(\*DATA); __DATA__ <?xml version="1.0" encoding="UTF-8"?> <sub-group-tree> ...

If you do mind that the rules would have to be modified to keep the data and you would have to traverse the returned data structure again, because with XML::Rules, the child tags are processed before their parent tags. (Well, there is a way to do something once the opening tag is parsed, but at that time no data from any child tags is accessible so you would not have access to the IP addresses.)

Jenda
Enoch was right!
Enjoy the last years of Rome.