Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
7.1 KiB

  1. package PPM::XML::Element;
  2. use vars qw( $VERSION );
  3. #
  4. # PPM::XML::Element
  5. #
  6. # Base class for XML Elements. Provides the ability to output the XML document
  7. # once it's been parsed using the XML::Parser module.
  8. #
  9. ###############################################################################
  10. $VERSION = do { my @r = q$Revision: 1.7 $ =~ /\d+/g; sprintf '%d.'.'%02d'x$#r, @r };
  11. ###############################################################################
  12. # Required inclusions.
  13. ###############################################################################
  14. use HTML::Entities; # Needed for escaping char entities
  15. ###############################################################################
  16. # Allow for creation via 'new'.
  17. ###############################################################################
  18. sub new
  19. {
  20. my ($class, %args) = @_;
  21. bless \%args, $class;
  22. }
  23. ###############################################################################
  24. # Subroutine: output
  25. ###############################################################################
  26. # Outputs the entire XML document on the currently selected filehandle.
  27. ###############################################################################
  28. sub output
  29. {
  30. my $self = shift;
  31. print $self->as_text();
  32. }
  33. ###############################################################################
  34. # Subroutine: content
  35. ###############################################################################
  36. # Returns a string containing all of the content of this element.
  37. ###############################################################################
  38. sub content
  39. {
  40. my $self = shift;
  41. my @kids = @{ $self->{'Kids'} };
  42. my $text;
  43. if (@kids > 0)
  44. {
  45. foreach (@kids)
  46. {
  47. # Allow for outputting of char data
  48. if ((ref $_) =~ /::Characters$/o)
  49. { $text .= encode_entities( $_->{'Text'} ); }
  50. else
  51. { $text .= $_->as_text(); }
  52. }
  53. }
  54. return $text;
  55. }
  56. ###############################################################################
  57. # Subroutine: add_child ($elemref)
  58. ###############################################################################
  59. # Adds a new child element to ourselves.
  60. ###############################################################################
  61. sub add_child (\$)
  62. {
  63. my $self = shift;
  64. my $elemref = shift;
  65. push( @{$self->{'Kids'}}, $elemref );
  66. }
  67. ###############################################################################
  68. # Subroutine: remove_child ($elemref)
  69. ###############################################################################
  70. # Removes a child element from ourselves. Returns non-zero if it was able to
  71. # remove the child element, and zero if it was unable to do so.
  72. ###############################################################################
  73. sub remove_child
  74. {
  75. my $self = shift;
  76. my $elemref = shift;
  77. foreach my $idx (0 .. @{$self->{'Kids'}})
  78. {
  79. if ($self->{'Kids'}[$idx] == $elemref)
  80. {
  81. splice( @{$self->{'Kids'}}, $idx, 1 );
  82. return 1;
  83. }
  84. }
  85. return 0;
  86. }
  87. ###############################################################################
  88. # Subroutine: add_text ($text)
  89. ###############################################################################
  90. # Adds character data to the given element. Returns undef if unable to add the
  91. # text to this element, and returns a reference to the character data element
  92. # if successful.
  93. ###############################################################################
  94. sub add_text
  95. {
  96. my $self = shift;
  97. my $text = shift;
  98. return if (!defined $text);
  99. my $type = ref $self; # Do package name magic
  100. $type =~ s/::[^:]+?$/::Characters/o;
  101. my $elem = new $type;
  102. $elem->{'Text'} = $text;
  103. $self->add_child( $elem );
  104. return $elem;
  105. }
  106. ###############################################################################
  107. # Subroutine: as_text
  108. ###############################################################################
  109. # Returns a string containing the entire XML document.
  110. ###############################################################################
  111. sub as_text
  112. {
  113. my $self = shift;
  114. my $text;
  115. my $type = ref $self;
  116. $type =~ s/.*:://;
  117. $text = '<' . $type;
  118. foreach (sort keys %{$self})
  119. {
  120. if ($_ !~ /Text|Kids/)
  121. { $text .= " $_=\"" . $self->{$_} . '"'; }
  122. }
  123. my $cont = $self->content();
  124. if (defined $cont)
  125. { $text .= '>' . $cont . '</' . $type . '>'; }
  126. else
  127. { $text .= ' />'; }
  128. return $text;
  129. }
  130. __END__
  131. ###############################################################################
  132. # PPD Documentation
  133. ###############################################################################
  134. =head1 NAME
  135. PPM::XML::Element - Base element class for XML elements
  136. =head1 SYNOPSIS
  137. use PPM::XML::Element;
  138. @ISA = qw( PPM::XML::Element );
  139. =head1 DESCRIPTION
  140. Base element class for XML elements. To be derived from to create your own
  141. elements for use with the XML::Parser module. Supports output of empty
  142. elements using <.... />.
  143. It is recommended that you use a version of the XML::Parser module which
  144. includes support for Styles; by deriving your own elements from
  145. PPM::XML::Element and using the 'Objects' style it becomes B<much> easier
  146. to create your own parser.
  147. =head1 METHODS
  148. =over 4
  149. =item add_text ($text)
  150. Adds character data to the end of the element. The element created is placed
  151. within the same package space as the element it was created under (e.g. adding
  152. text to a XML::Foobar::Stuff element would put the character data into an
  153. XML::Foobar::Characters element). If successful, this method returns a
  154. reference to the newly created element.
  155. =item as_text
  156. Returns a string value containing the entire XML document from this element on
  157. down.
  158. =item content
  159. Returns a string value containing the entire content of this XML element. Note
  160. that this is quite similar to the C<as_text()> method except that it does not
  161. include any information about this element in particular.
  162. =item output
  163. Recursively outputs the structure of the XML document from this element on
  164. down.
  165. =item add_child ($elemref)
  166. Adds the child element to the list of children for this element. Note that
  167. the element given must be a reference to an object derived from
  168. C<PPM::XML::Element>.
  169. =item remove_child ($elemref)
  170. Removes the given child element from the list of children for this element.
  171. This method returns non-zero if it is able to locate and remove the child
  172. element, returning zero if it is unable to do so.
  173. =back
  174. =head1 LIMITATIONS
  175. The C<PPM::XML::Element> module has no provisions for outputting processor
  176. directives or external entities. It only outputs child elements and any
  177. character data which the elements may contain.
  178. =head1 AUTHORS
  179. Graham TerMarsch <[email protected]>
  180. =head1 SEE ALSO
  181. L<XML::Parser>
  182. =cut