5 package XML::TemplateSAX::Handler;
6 use base qw(XML::SAX::Base);
13 obj => $options{'Content'},
15 Handler => $options{'Handler'}
22 my ($self, $data) = @_;
23 my $obj = $self->{'obj'};
26 my $id = $data->{'Attributes'}->{'{http://template.sesse.net/}id'};
27 $id = $id->{'Value'} if (defined($id));
29 # within a replacement; just ignore everything
30 return if (!defined($obj));
32 # substitution: see if this element matches anything. if so,
33 # descend down into the tree.
34 if (ref($obj) eq 'HASH') {
36 for my $key (keys %$obj) {
37 if ($key =~ /^#(.*)$/) {
38 if (defined($id) && $id eq $1) {
39 $match = $obj->{$key};
43 if ($data->{'LocalName'} eq $key) {
44 $match = $obj->{$key};
50 if (defined($match)) {
51 $self->SUPER::start_element($data);
53 push @{$self->{'stack'}}, [ $data->{'Name'}, $obj ];
56 # This is sort of ugly. We special-case replacement by outputting
57 # the string immediately, and then just ignoring the rest of the
58 # events until we get to the right end tag. It's not 100% technically
59 # correct for the case where you replace an entire document by a
60 # string, but that's nonsensical anyway.
63 $self->SUPER::characters({ Data => $match });
67 $self->{'obj'} = $match;
72 $self->SUPER::start_element($data);
76 my ($self, $data) = @_;
77 return if (!defined($self->{'obj'}));
78 $self->SUPER::characters($data);
82 my ($self, $data) = @_;
84 my $stack = $self->{'stack'};
85 if (scalar @$stack > 0) {
86 my $top = $stack->[$#stack];
88 if ($data->{'Name'} eq $top->[0]) {
89 $self->SUPER::end_element($data);
90 $self->{'obj'} = $top->[1];
96 return if (!defined($self->{'obj'}));
98 $self->SUPER::end_element($data);