--- /dev/null
+#! /usr/bin/perl
+
+# A utility class that can store SAX events and replay them back to some SAX
+# handler as many times as you'd like. Useful for both cloning and including.
+
+package XML::TemplateSAX::Buffer;
+use base qw(XML::SAX::Base);
+
+sub new {
+ my $class = shift;
+ my %options = @_;
+
+ my $self = {
+ events => []
+ };
+ bless($self, $class);
+ return $self;
+}
+
+sub start_element {
+ my ($self, $data) = @_;
+ push @{$self->{'events'}}, [ 'E', $data ];
+}
+
+sub characters {
+ my ($self, $data) = @_;
+ push @{$self->{'events'}}, [ 'C', $data ];
+}
+
+sub comment {
+ my ($self, $data) = @_;
+ push @{$self->{'events'}}, [ 'c', $data ];
+}
+
+sub processing_instruction {
+ my ($self, $data) = @_;
+ push @{$self->{'events'}}, [ 'p', $data ];
+}
+
+sub end_element {
+ my ($self, $data) = @_;
+ push @{$self->{'events'}}, [ 'e', $data ];
+}
+
+sub replay {
+ my ($self, $dest) = @_;
+
+ for my $event (@{$self->{'events'}}) {
+ my ($type, $data) = @$event;
+ if ($type eq 'E') {
+ $dest->start_element($data);
+ } elsif ($type eq 'C') {
+ $dest->characters($data);
+ } elsif ($type eq 'c') {
+ $dest->comment($data);
+ } elsif ($type eq 'p') {
+ $dest->processing_instruction($data);
+ } elsif ($type eq 'e') {
+ $dest->end_element($data);
+ }
+ }
+}
+
+1;