package PPM::XML::Element; # # PPM::XML::Element # # Base class for XML Elements. Provides the ability to output the XML document # once it's been parsed using the XML::Parser module. # ############################################################################### ############################################################################### # Required inclusions. ############################################################################### use HTML::Entities; # Needed for escaping char entities ############################################################################### # Allow for creation via 'new'. ############################################################################### sub new { my ($class, %args) = @_; bless \%args, $class; } ############################################################################### # Subroutine: output ############################################################################### # Outputs the entire XML document on the currently selected filehandle. ############################################################################### sub output { my $self = shift; print $self->as_text(); } ############################################################################### # Subroutine: content ############################################################################### # Returns a string containing all of the content of this element. ############################################################################### sub content { my $self = shift; my $kids = $self->{'Kids'}; return unless (defined $kids and ref($kids) eq 'ARRAY'); my @kids = @{ $kids }; my $text; if (@kids > 0) { foreach (@kids) { # Allow for outputting of char data if ((ref $_) =~ /::Characters$/o) { $text .= encode_entities( $_->{'Text'} ); } else { $text .= $_->as_text(); } } } return $text; } ############################################################################### # Subroutine: add_child ($elemref) ############################################################################### # Adds a new child element to ourselves. ############################################################################### sub add_child (\$) { my $self = shift; my $elemref = shift; push( @{$self->{'Kids'}}, $elemref ); } ############################################################################### # Subroutine: remove_child ($elemref) ############################################################################### # Removes a child element from ourselves. Returns non-zero if it was able to # remove the child element, and zero if it was unable to do so. ############################################################################### sub remove_child { my $self = shift; my $elemref = shift; foreach my $idx (0 .. @{$self->{'Kids'}}) { if ($self->{'Kids'}[$idx] == $elemref) { splice( @{$self->{'Kids'}}, $idx, 1 ); return 1; } } return 0; } ############################################################################### # Subroutine: add_text ($text) ############################################################################### # Adds character data to the given element. Returns undef if unable to add the # text to this element, and returns a reference to the character data element # if successful. ############################################################################### sub add_text { my $self = shift; my $text = shift; return if (!defined $text); my $type = ref $self; # Do package name magic $type =~ s/::[^:]+?$/::Characters/o; my $elem = new $type; $elem->{'Text'} = $text; $self->add_child( $elem ); return $elem; } ############################################################################### # Subroutine: as_text ############################################################################### # Returns a string containing the entire XML document. ############################################################################### sub as_text { my $self = shift; my $text; my $type = ref $self; $type =~ s/.*:://; $text = "\n<" . $type; foreach (sort keys %{$self}) { if ($_ !~ /Text|Kids/) { if (defined $self->{$_} ) { $text .= " $_=\"" . $self->{$_} . '"'; } } } my $cont = $self->content(); if (defined $cont) { $text .= '>' . $cont . ''; } else { $text .= ' />'; } $text =~ s/\n\n/\n/g; return $text; } 1; __END__ ############################################################################### # PPD Documentation ############################################################################### =head1 NAME PPM::XML::Element - Base element class for XML elements =head1 SYNOPSIS use PPM::XML::Element; @ISA = qw( PPM::XML::Element ); =head1 DESCRIPTION Base element class for XML elements. To be derived from to create your own elements for use with the XML::Parser module. Supports output of empty elements using <.... />. It is recommended that you use a version of the XML::Parser module which includes support for Styles; by deriving your own elements from PPM::XML::Element and using the 'Objects' style it becomes B easier to create your own parser. =head1 METHODS =over 4 =item add_text ($text) Adds character data to the end of the element. The element created is placed within the same package space as the element it was created under (e.g. adding text to a XML::Foobar::Stuff element would put the character data into an XML::Foobar::Characters element). If successful, this method returns a reference to the newly created element. =item as_text Returns a string value containing the entire XML document from this element on down. =item content Returns a string value containing the entire content of this XML element. Note that this is quite similar to the C method except that it does not include any information about this element in particular. =item output Recursively outputs the structure of the XML document from this element on down. =item add_child ($elemref) Adds the child element to the list of children for this element. Note that the element given must be a reference to an object derived from C. =item remove_child ($elemref) Removes the given child element from the list of children for this element. This method returns non-zero if it is able to locate and remove the child element, returning zero if it is unable to do so. =back =head1 LIMITATIONS The C module has no provisions for outputting processor directives or external entities. It only outputs child elements and any character data which the elements may contain. =head1 AUTHORS Graham TerMarsch =head1 SEE ALSO L =cut