X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=perl-sax%2FXML%2FTemplateSAX%2FHandler.pm;h=319883bfd6ad883938bbab26d64a42bc5d6352ed;hb=fcd2b8ecd1668b302e6000a10d307d537b5c432f;hp=93c19870aad87871472c89e2c3eea7751f7126ed;hpb=f91b0828ee341cb09381e535538f5c8865486731;p=xml-template diff --git a/perl-sax/XML/TemplateSAX/Handler.pm b/perl-sax/XML/TemplateSAX/Handler.pm index 93c1987..319883b 100644 --- a/perl-sax/XML/TemplateSAX/Handler.pm +++ b/perl-sax/XML/TemplateSAX/Handler.pm @@ -14,6 +14,7 @@ sub new { my $self = { obj => $options{'Content'}, stack => [], + level => 0, Handler => $options{'Handler'} }; bless($self, $class); @@ -24,6 +25,8 @@ sub start_element { my ($self, $data) = @_; my $obj = $self->{'obj'}; + ++$self->{'level'}; + # find the ID, if any my $id = $data->{'Attributes'}->{'{http://template.sesse.net/}id'}; $id = $id->{'Value'} if (defined($id)); @@ -40,6 +43,23 @@ sub start_element { # substitution: see if this element matches anything. if so, # descend down into the tree. if (ref($obj) eq 'HASH') { + # first of all, see if we have an attribute match. + for my $key (keys %$obj) { + next unless ($key =~ /^(#?)(.*)\/(.*)$/); + my ($idmarker, $name, $attr) = ($1, $2, $3); + + if (($idmarker eq '#' && $id eq $name) || + ($idmarker ne '#' && $data->{'LocalName'} eq $name)) { + $data->{'Attributes'}->{$attr} = { + Prefix => '', + LocalName => $attr, + Name => $attr, + NamespaceURI => '', + Value => $obj->{$key} + }; + } + } + my $match = undef; for my $key (keys %$obj) { if ($key =~ /^#(.*)$/) { @@ -57,8 +77,8 @@ sub start_element { if (defined($match)) { $self->SUPER::start_element($data); - - push @{$self->{'stack'}}, [ $data->{'Name'}, $obj ]; + + push @{$self->{'stack'}}, [ $self->{'level'}, $obj ]; # # This is sort of ugly. We special-case replacement by outputting @@ -85,8 +105,20 @@ sub start_element { $self->{'obj'} = XML::TemplateSAX::Buffer->new($match); return; } - - $self->{'obj'} = $match; + + # + # If someone tries to insert a full tree, do it, just like the character + # replacement above. + # + if (ref($match) eq 'XML::TemplateSAX::Buffer') { + $match->replay($self); + $self->{'obj'} = undef; + } elsif (ref($match) eq 'XML::TemplateSAX::Deferred') { + $match->parse($self); + $self->{'obj'} = undef; + } else { + $self->{'obj'} = $match; + } return; } } @@ -136,12 +168,12 @@ sub processing_instruction { sub end_element { my ($self, $data) = @_; - + my $stack = $self->{'stack'}; if (scalar @$stack > 0) { my $top = $stack->[scalar @$stack - 1]; - if ($data->{'Name'} eq $top->[0]) { + if ($self->{'level'} == $top->[0]) { my $obj = $self->{'obj'}; # did we just finish a clone operation? @@ -155,10 +187,13 @@ sub end_element { $self->SUPER::end_element($data); $self->{'obj'} = $top->[1]; pop @$stack; + --$self->{'level'}; return; } } + --$self->{'level'}; + return if (!defined($self->{'obj'})); if (ref($self->{'obj'}) eq 'XML::TemplateSAX::Buffer') {