From 0e42fe54bced5dacf4557f94df50c2ca126a16c8 Mon Sep 17 00:00:00 2001 From: "sgunderson@bigfoot.com" <> Date: Thu, 1 Mar 2007 02:58:49 +0100 Subject: [PATCH] Make perl-sax/simple almost work. --- perl-sax/XML/TemplateSAX.pm | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/perl-sax/XML/TemplateSAX.pm b/perl-sax/XML/TemplateSAX.pm index fce9ae2..d2eb7a5 100644 --- a/perl-sax/XML/TemplateSAX.pm +++ b/perl-sax/XML/TemplateSAX.pm @@ -17,6 +17,7 @@ use XML::SAX::Expat; use XML::SAX::Writer; +use Data::Dumper; package XML::TemplateSAX::Handler; use base qw(XML::SAX::Base); @@ -27,6 +28,7 @@ sub new { my $self = { obj => $options{'Content'}, + stack => [], Handler => $options{'Handler'} }; bless($self, $class); @@ -35,10 +37,80 @@ sub new { sub start_element { my ($self, $data) = @_; + my $obj = $self->{'obj'}; + # within a replacement; just ignore everything + return if (!defined($obj)); + + # substitution: see if this element matches anything. if so, + # descend down into the tree. + if (ref($obj) eq 'HASH') { + my $match = undef; + for my $key (keys %$obj) { + if ($key =~ /^#(.*)$/) { + if ($data->{'NamespaceURI'} eq 'http://template.sesse.net/' && $data->{'LocalName'} eq $1) { + $match = $obj->{$key}; + last; + } + } else { + if ($data->{'LocalName'} eq $key) { + $match = $obj->{$key}; + last; + } + } + } + + if (defined($match)) { + $self->SUPER::start_element($data); + + push @{$self->{'stack'}}, [ $data->{'Name'}, $obj ]; + + # + # This is sort of ugly. We special-case replacement by outputting + # the string immediately, and then just ignoring the rest of the + # events until we get to the right end tag. It's not 100% technically + # correct for the case where you replace an entire document by a + # string, but that's nonsensical anyway. + # + if (!ref($match)) { + $self->SUPER::characters({ Data => $match }); + $match = undef; + } + + $self->{'obj'} = $match; + return; + } + } + $self->SUPER::start_element($data); } +sub characters { + my ($self, $data) = @_; + return if (!defined($self->{'obj'})); + $self->SUPER::characters($data); +} + +sub end_element { + my ($self, $data) = @_; + + my $stack = $self->{'stack'}; + if (scalar @$stack > 0) { + my $top = $stack->[$#stack]; + + if ($data->{'Name'} eq $top->[0]) { + $self->SUPER::end_element($data); + $self->{'obj'} = $top->[1]; + pop @$stack; + return; + } + } + + return if (!defined($self->{'obj'})); + + $self->SUPER::end_element($data); +} + package XML::TemplateSAX; sub process_file { -- 2.39.5