use XML::SAX::Expat;
use XML::SAX::Writer;
-use Data::Dumper;
-
-package XML::TemplateSAX::Handler;
-use base qw(XML::SAX::Base);
-
-sub new {
- my $class = shift;
- my %options = @_;
-
- my $self = {
- obj => $options{'Content'},
- stack => [],
- Handler => $options{'Handler'}
- };
- bless($self, $class);
- return $self;
-}
-
-sub start_element {
- my ($self, $data) = @_;
- my $obj = $self->{'obj'};
-
- # find the ID, if any
- my $id = $data->{'Attributes'}->{'{http://template.sesse.net/}id'};
- $id = $id->{'Value'} if (defined($id));
-
- # 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 (defined($id) && $id 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::Cleaner;
-use base qw(XML::SAX::Base);
-
-sub start_element {
- my ($self, $data) = @_;
- my $attrs = $data->{'Attributes'};
-
- for my $a (keys %$attrs) {
- if ($attrs->{$a}->{'NamespaceURI'} eq 'http://template.sesse.net/') {
- delete $attrs->{$a};
- }
- }
-
- $self->SUPER::start_element($data);
-}
+use XML::TemplateSAX::Cleaner;
+use XML::TemplateSAX::Handler;
package XML::TemplateSAX;
--- /dev/null
+#! /usr/bin/perl
+
+use Data::Dumper;
+
+package XML::TemplateSAX::Handler;
+use base qw(XML::SAX::Base);
+
+sub new {
+ my $class = shift;
+ my %options = @_;
+
+ my $self = {
+ obj => $options{'Content'},
+ stack => [],
+ Handler => $options{'Handler'}
+ };
+ bless($self, $class);
+ return $self;
+}
+
+sub start_element {
+ my ($self, $data) = @_;
+ my $obj = $self->{'obj'};
+
+ # find the ID, if any
+ my $id = $data->{'Attributes'}->{'{http://template.sesse.net/}id'};
+ $id = $id->{'Value'} if (defined($id));
+
+ # 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 (defined($id) && $id 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);
+}
+
+1;