#!/usr/bin/perl use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); use XML::Simple qw(:strict); run(); sub run { my $xml = XMLin( <<'END', ForceArray => ['parameters'], KeyAttr => ['declaration_name', 'name']); END my @list; my $sub = sub {push(@list, shift(@_) . ": " . join(" => ", @_))}; findPath($sub, $xml, "pciReg"); findPath($sub, $xml, "DIRTY"); findPath($sub, $xml, "parameters"); print join("\n", @list), "\n"; } sub findPath { my ($sub, $xmlFrag, $match, @path) = @_; return unless $xmlFrag; if (ref($xmlFrag) =~ /HASH/) { for my $key (sort keys %$xmlFrag) { if ($key !~ /$match/) { findPath($sub, $xmlFrag->{$key}, $match, @path, $key); } else { $sub->($match, @path); } } } elsif (ref($xmlFrag) =~ /ARRAY/) { for my $fragIdx (0 .. $#$xmlFrag) { unless ($xmlFrag->[$fragIdx] =~ /$match/) { findPath($sub, $xmlFrag->[$fragIdx], $match, @path, $fragIdx + 1); } else { $sub->($match, @path); } } } return; } #### pciReg: public_methods => members => parameters DIRTY: enums => members => values parameters: public_methods => members