#!/usr/bin/perl use warnings FATAL => qw(all); use strict; use Data::Dump qw(dump pp); use XML::Simple qw(:strict); use Data::Dumper; run(); sub run { my $xml = XMLin( <<'END', ForceArray => ['parameters'], KeyAttr => ['declaratio +n_name', 'name']); <classes name="Panoply::BAR"> <public_methods> <members name="BAR" const="no" kind="function" protection="publi +c" static="no" virtualness="non_virtual" volatile="no"> <parameters declaration_name="pciReg" type="Register::Ptr" /> </members> <members name="bits" const="no" kind="function" protection="publ +ic" static="no" type="void" virtualness="non_virtual" volatile="no"> <parameters declaration_name="value" type="uint64_t" /> </members> <members name="subBitVector" const="no" kind="function" protecti +on="public" static="no" type="void" virtualness="non_virtual" volatil +e="no"> <parameters declaration_name="value" type="const BitVector &am +p;" /> </members> </public_methods> <enums> <members name="ObjectState" kind="enum" protection="public" stat +ic="no" virtualness="non_virtual"> <values name="NEW"> </values> <values name="REFRESHED"> </values> <values name="DIRTY"> </values> </members> </enums> </classes> END my @list; my $sub = sub {push(@list, shift(@_) . ": " . join(" => ", @_))}; findPath($sub, $xml, "value"); 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; }
In reply to finding ancestor elements related to specific change by jccunning
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |