#!/usr/local/bin/perl
use XML::Parser;
my $file = shift;
die "Can't find file \"$file\"" unless -f $file;
my $parser = new XML::Parser(Style => Tree, ErrorContext => 2);
my $pairref = $parser->parsefile($file);

$VISIBILITY = 'Foundation\.Core\.ModelElement\.visibility';
$CLASS = 'Foundation\.Core\.Class$';
$NAME = 'Foundation\.Core\.ModelElement\.name$';
$ATTRIBUTE = 'Foundation\.Core\.Attribute';

mypair(undef, undef, @$pairref);

# take hashrefs for current class and attribute, plus tag-content pair
sub mypair {
  my ($recclass, $recattr, $tag, $content) = @_;
  return $content unless $tag; # deal with non-element nodes, i.e. text
  if ($tag=~/$ATTRIBUTE/) {
    my $attr = {}; # the attr we've found, rep by new ref to anon hash
    myarray($recclass, $attr, @$content); 
    print "Attr $$attr{name} in class $$recclass{name} is public\n" 
      if $$attr{visibility} =~ 'public';
  }
  elsif ($tag=~/$VISIBILITY/ && $recattr)
    { $$recattr{visibility} = ${$$content[0]}{'xmi.value'}; } 
  elsif ($tag=~/$NAME/ && $recattr){$$recattr{name} = @$content[2];}
  elsif ($tag=~/$CLASS/) {myarray({}, $recattr, @$content);}
  elsif ($tag=~/$NAME/) {
    $$recclass{name} = @$content[2] unless $$recclass{name};
  }
  else { myarray($recclass, $recattr, @$content); }
}

# take hashrefs for current class and attribute, plus an element content, viz
# a hashref for attributes, which we ignore, followed by (tag,content)*
sub myarray {
  my ($class, $attr, $attributes, @rest) = @_;
  while (@rest) {
    mypair ($class, $attr, shift @rest, shift @rest);
  }
}
