# # SAX Filter to follow XLinks and basically # transform them into XIncludes. # # code by Brad Lhotsky # package XML::Expander::Filter::XLink; use 5.006; use strict; use warnings; use base qw(XML::SAX::Base); use XML::Expander; use LWP::Simple; use Data::Dumper; our $VERSION = 0.01; our $DEBUG = 1; #our $AUTOLOAD; XML::Expander::Filter::XLink->_debug("USED ME"); sub start_element { my ($self,$el) = @_; $self->_debug("starting an element $el->{LocalName}"); my $attrs = $el->{Attributes}; my $xlink = undef; my %link = (); foreach my $a (keys %$attrs) { next unless $attrs->{$a}{NamespaceURI} eq 'http://www.w3.org/1999/xlink'; $link{$attrs->{$a}{LocalName}} = $attrs->{$a}{Value}; $xlink ||= $el->{LocalName}; } return $self->SUPER::start_element($el) unless $xlink; $self->_debug("* found an xlink"); print Dumper ( \%link ); # # this where we incorporate the rest of the document if its # an xlink and stuff $self->{xlink_linked} = 1; my @lnx = qw/simple locator/; if($link{href}) { delete $self->{xlink_linked}; my $parser = XML::SAX::ParserFactory->parser( { Handler => $self} ); my $content = $self->retrieve($link{href}); print $content; $parser->parse_string( $content ); $self->{xlink_linked} = 1; return; } # # we should only get here if we have an xlinked we don't # understand, so lets make this safe delete $self->{xlink_linked}; return $self->SUPER::start_element($el); } sub end_element { my $self = shift; if($self->{xlink_linked}) { delete $self->{xlink_linked}; return; } $self->SUPER::end_element(@_); } sub characters { my $self = shift; return if $self->{xlink_linked}; $self->SUPER::characters(@_); } sub retrieve { my ($self,$uri) = @_; return get($uri); } #sub AUTOLOAD { # my ($self) = shift; # $self->_debug("Attempting to AUTOLOAD $AUTOLOAD"); # my $func = 'SUPER::' . (split /\:\:/, $AUTOLOAD)[-1]; # $self->_debug("fucntion: $func"); # #no strict 'refs'; # #$self->$func(@_); #} sub _debug { return unless $DEBUG; my ($self,@msgs) = @_; my $time = join ':', map { unless( /^\d\d$/ ) { s/^/0/; } $_; } (localtime)[2,1,0]; for(@msgs) { chomp; print STDERR "$time DEBUG> $_\n"; } } 1;