home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / share / perl5 / XML / Grove / Subst.pm < prev    next >
Encoding:
Text File  |  1999-10-23  |  5.1 KB  |  226 lines

  1. #
  2. # Copyright (C) 1998 Ken MacLeod
  3. # XML::Grove::Subst is free software; you can redistribute it
  4. # and/or modify it under the same terms as Perl itself.
  5. #
  6. # $Id: Subst.pm,v 1.3 1999/08/25 16:49:32 kmacleod Exp $
  7. #
  8.  
  9. use strict;
  10.  
  11. package XML::Grove::Subst;
  12.  
  13. sub new {
  14.     my $class = shift;
  15.  
  16.     return bless {}, $class;
  17. }
  18.  
  19. sub subst {
  20.     my $self = shift;
  21.     my $grove_fragment = shift;
  22.     my $args = [ @_ ];
  23.  
  24.     return ($grove_fragment->accept($self, $args));
  25. }
  26.  
  27. sub subst_hash {
  28.     my $self = shift;
  29.     my $grove_fragment = shift;
  30.     my $args = shift;
  31.  
  32.     return ($grove_fragment->accept($self, $args));
  33. }
  34.  
  35. sub visit_document {
  36.     my $self = shift; my $document = shift;
  37.  
  38.     my $contents = [ $document->children_accept ($self, @_) ];
  39.  
  40.     return
  41.       XML::Grove::Document->new( Contents => $contents );
  42. }
  43.  
  44. sub visit_element {
  45.     my $self = shift; my $element = shift;
  46.  
  47.     my $name = $element->{Name};
  48.     if ($name eq 'SUB:key') {
  49.     my $subst = $_[0]{$element->{Attributes}{'key'}};
  50.     if (ref($subst) eq 'ARRAY') {
  51.         return @$subst;
  52.     } else {
  53.         if (ref($subst)) {
  54.         return $subst;
  55.         } else {
  56.         return XML::Grove::Characters->new( Data => $subst );
  57.         }
  58.     }
  59.     } elsif ($name =~ /^SUB:(.*)$/) {
  60.     my $subst = $_[0][$1 - 1];
  61.     if (ref($subst) eq 'ARRAY') {
  62.         return @$subst;
  63.     } else {
  64.         if (ref($subst)) {
  65.         return $subst;
  66.         } else {
  67.         return XML::Grove::Characters->new( Data => $subst );
  68.         }
  69.     }
  70.     }
  71.  
  72.     my $contents = [ $element->children_accept ($self, @_) ];
  73.  
  74.     return
  75.       XML::Grove::Element->new( Name => $name,
  76.                 Nttributes => $element->{Attributes},
  77.                 Contents => $contents );
  78. }
  79.  
  80. sub visit_pi {
  81.     my $self = shift; my $pi = shift;
  82.  
  83.     return $pi;
  84. }
  85.  
  86. sub visit_characters {
  87.     my $self = shift; my $characters = shift;
  88.  
  89.     return $characters;
  90. }
  91.  
  92. ###
  93. ### Extend the XML::Grove::Document and XML::Grove::Element packages with our
  94. ### new function.
  95. ###
  96.  
  97. package XML::Grove::Document;
  98.  
  99. sub subst {
  100.     my $self = shift;
  101.  
  102.     return (XML::Grove::Subst->new->subst($self, @_));
  103. }
  104.  
  105. sub subst_hash {
  106.     my $self = shift;
  107.  
  108.     return (XML::Grove::Subst->new->subst_hash($self, @_));
  109. }
  110.  
  111. package XML::Grove::Element;
  112.  
  113. sub subst {
  114.     my $self = shift;
  115.  
  116.     return (XML::Grove::Subst->new->subst($self, @_));
  117. }
  118.  
  119. sub subst_hash {
  120.     my $self = shift;
  121.  
  122.     return (XML::Grove::Subst->new->subst_hash($self, @_));
  123. }
  124.  
  125. 1;
  126.  
  127. __END__
  128.  
  129. =head1 NAME
  130.  
  131. XML::Grove::Subst - substitute values into a template
  132.  
  133. =head1 SYNOPSIS
  134.  
  135.  use XML::Grove::Subst;
  136.  
  137.  # Using subst method on XML::Grove::Document or XML::Grove::Element:
  138.  $new_grove = $source_grove->subst( ARGS );
  139.  $new_grove = $source_grove->subst_hash( ARG );
  140.  
  141.  # Using an XML::Grove::Subst instance:
  142.  $subster = XML::Grove::Subst->new();
  143.  $new_grove = $subster->subst( $source_grove, ARGS );
  144.  $new_grove = $subster->subst_hash( $source_grove, ARG );
  145.  
  146. =head1 DESCRIPTION
  147.  
  148. C<XML::Grove::Subst> implements XML templates.  C<XML::Grove::Subst>
  149. traverses through a source grove replacing all elements with names
  150. `C<SUB:XXX>' or `C<SUB:key>' with their corresponding values from ARGS (a
  151. list) or ARG (a hash), repsectively.
  152.  
  153. =head1 METHODS
  154.  
  155. =over 4
  156.  
  157. =item $grove_obj->subst( I<ARGS> )
  158. =item $subster->subst( $grove_obj, I<ARGS> )
  159.  
  160. Search for `C<SUB:I<XXX>>' elements, where I<XXX> is an array index,
  161. and replace the element with the value from I<ARGS>, a list of values.
  162. The return value is a new grove with the substitutions applied.
  163.  
  164. =item $grove_obj->subst_hash( I<ARG> )
  165. =item $subster->subst_hash( $grove_obj, I<ARG> )
  166.  
  167. Search for `C<SUB:key>' elements and replace the element with the
  168. value from I<ARG>, a hash of values.  The hash key is taken from the
  169. `C<key>' attribute of the `C<SUB:key>' element, for example,
  170. `C<E<lt>SUB:key key='foo'E<gt>>'.  The return value is a new grove
  171. with the substitutions applied.
  172.  
  173. =head1 EXAMPLE
  174.  
  175. The following template, in a file `C<template.xml>', could be used for
  176. a simple parts database conversion to HTML:
  177.  
  178.     <html>
  179.       <head>
  180.         <title><SUB:key key='Name'></title>
  181.       </head>
  182.       <body>
  183.         <h1><SUB:key key='Name'></title>
  184.         <p>Information for part number <SUB:key key='Number'>:</p>
  185.         <SUB:key key='Description'>
  186.       </body>
  187.     </html>
  188.  
  189. To use this template you would first parse it and convert it to a
  190. grove, and then use `C<subst_hash()>' every time you needed a new
  191. page:
  192.  
  193.     use XML::Parser::PerlSAX;
  194.     use XML::Grove;
  195.     use XML::Grove::Builder;
  196.     use XML::Grove::Subst;
  197.     use XML::Grove::PerlSAX;
  198.     use XML::Handler::XMLWriter;
  199.  
  200.     # Load the template
  201.     $b = XML::Grove::Builder->new();
  202.     $p = XML::Parser::PerlSAX->new( Handler = $b );
  203.     $source_grove = $p->parse( Source => { SystemId => 'template.xml' } );
  204.  
  205.     # Apply the substitutions
  206.     $new_grove = $source_grove->subst_hash( { Name => 'Acme DCX-2000 Filter',
  207.                           Number => 'N4728',
  208.                           Description => 'The Best' } );
  209.  
  210.     # Write the new grove to standard output
  211.     $w = XML::Handler::XMLWriter->new();
  212.     $wp = XML::Grove::PerlSAX->new( Handler => $w );
  213.     $wp->parse( Source => { Grove => $new_grove } );
  214.  
  215. =head1 AUTHOR
  216.  
  217. Ken MacLeod, ken@bitsko.slc.ut.us
  218.  
  219. =head1 SEE ALSO
  220.  
  221. perl(1), XML::Grove(3)
  222.  
  223. Extensible Markup Language (XML) <http://www.w3c.org/XML>
  224.  
  225. =cut
  226.