X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=perl-sax%2FXML%2FTemplateSAX%2FHandler.pm;h=47ba62aa8ee0fdf6d3bfb279a7e525a81dcb6fc9;hb=2ab1d6484612b3c908085b6168326ac925302c0d;hp=24371cebe180a5d26e08d3ca0b13fc93cbef7da8;hpb=672fc78eaa0837b59d90d0926433739aeac1f93b;p=xml-template diff --git a/perl-sax/XML/TemplateSAX/Handler.pm b/perl-sax/XML/TemplateSAX/Handler.pm index 24371ce..47ba62a 100644 --- a/perl-sax/XML/TemplateSAX/Handler.pm +++ b/perl-sax/XML/TemplateSAX/Handler.pm @@ -1,5 +1,6 @@ #! /usr/bin/perl +use strict; use Data::Dumper; package XML::TemplateSAX::Handler; @@ -29,6 +30,12 @@ sub start_element { # within a replacement; just ignore everything return if (!defined($obj)); + # within a cloning; slurp it up + if (ref($obj) eq 'XML::TemplateSAX::Buffer') { + $obj->start_element($data); + return; + } + # substitution: see if this element matches anything. if so, # descend down into the tree. if (ref($obj) eq 'HASH') { @@ -49,9 +56,9 @@ sub start_element { if (defined($match)) { $self->SUPER::start_element($data); - - push @{$self->{'stack'}}, [ $data->{'Name'}, $obj ]; + 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 @@ -61,31 +68,89 @@ sub start_element { # if (!ref($match)) { $self->SUPER::characters({ Data => $match }); - $match = undef; + $self->{'obj'} = undef; + return; } + # + # Sort of the same, for cloning. Cloning works by gobbling up all the all the + # input until the end element, and put it into a buffer. when we get to the end + # element, spew it all out again as many times as we need, onto ourselves so we + # get filtering etc. right. + # + # We let the buffer object keep the actual array, so we can fetch it out later. + # + if (ref($match) eq 'ARRAY') { + $self->{'obj'} = XML::TemplateSAX::Buffer->new($match); + return; + } + $self->{'obj'} = $match; return; } } + $self->SUPER::start_element($data); } sub characters { my ($self, $data) = @_; + return if (!defined($self->{'obj'})); + + if (ref($self->{'obj'}) eq 'XML::TemplateSAX::Buffer') { + $self->{'obj'}->characters($data); + return; + } + $self->SUPER::characters($data); } +sub comment { + my ($self, $data) = @_; + + return if (!defined($self->{'obj'})); + + if (ref($self->{'obj'}) eq 'XML::TemplateSAX::Buffer') { + $self->{'obj'}->comment($data); + return; + } + + $self->SUPER::comment($data); +} + +sub processing_instruction { + my ($self, $data) = @_; + + return if (!defined($self->{'obj'})); + + if (ref($self->{'obj'}) eq 'XML::TemplateSAX::Buffer') { + $self->{'obj'}->processing_instruction($data); + return; + } + + $self->SUPER::processing_instruction($data); +} + sub end_element { my ($self, $data) = @_; my $stack = $self->{'stack'}; if (scalar @$stack > 0) { - my $top = $stack->[$#stack]; + my $top = $stack->[scalar @$stack - 1]; if ($data->{'Name'} eq $top->[0]) { + my $obj = $self->{'obj'}; + + # did we just finish a clone operation? + if (ref($obj) eq 'XML::TemplateSAX::Buffer') { + for my $instance (@{$obj->{'ptr'}}) { + $self->{'obj'} = $instance; + $obj->replay($self); + } + } + $self->SUPER::end_element($data); $self->{'obj'} = $top->[1]; pop @$stack; @@ -94,6 +159,11 @@ sub end_element { } return if (!defined($self->{'obj'})); + + if (ref($self->{'obj'}) eq 'XML::TemplateSAX::Buffer') { + $self->{'obj'}->end_element($data); + return; + } $self->SUPER::end_element($data); }