diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2007-11-11 06:55:13 +0000 |
| commit | 3282be229999dc36c197b264d63063a18d136331 (patch) | |
| tree | 98a42db29d955b39e7bed1b599fdcc56c3a29de9 /lib/Template/Plugin/XML | |
| parent | cfdd733c17cfa4f1a43b827a656e9e53cc2524ac (diff) | |
| download | xxv-3282be229999dc36c197b264d63063a18d136331.tar.gz xxv-3282be229999dc36c197b264d63063a18d136331.tar.bz2 | |
* Update installation list with required modules
* Remove unused/doubled provided external perl moduls
Diffstat (limited to 'lib/Template/Plugin/XML')
| -rw-r--r-- | lib/Template/Plugin/XML/DOM.pm | 841 | ||||
| -rw-r--r-- | lib/Template/Plugin/XML/RSS.pm | 194 | ||||
| -rw-r--r-- | lib/Template/Plugin/XML/Simple.pm | 124 | ||||
| -rw-r--r-- | lib/Template/Plugin/XML/Style.pm | 357 | ||||
| -rw-r--r-- | lib/Template/Plugin/XML/XPath.pm | 284 |
5 files changed, 0 insertions, 1800 deletions
diff --git a/lib/Template/Plugin/XML/DOM.pm b/lib/Template/Plugin/XML/DOM.pm deleted file mode 100644 index 30bac3b..0000000 --- a/lib/Template/Plugin/XML/DOM.pm +++ /dev/null @@ -1,841 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::DOM -# -# DESCRIPTION -# -# Simple Template Toolkit plugin interfacing to the XML::DOM.pm module. -# -# AUTHORS -# Andy Wardley <abw@kfs.org> -# Simon Matthews <sam@knowledgepool.com> -# -# COPYRIGHT -# Copyright (C) 2000 Andy Wardley, Simon Matthews. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: DOM.pm,v 2.54 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::DOM; - -require 5.004; - -use strict; -use Template::Plugin; -use XML::DOM; - -use base qw( Template::Plugin ); -use vars qw( $VERSION $DEBUG ); - -$VERSION = 2.6; -$DEBUG = 0 unless defined $DEBUG; - - -#------------------------------------------------------------------------ -# new($context, \%config) -# -# Constructor method for XML::DOM plugin. Creates an XML::DOM::Parser -# object and initialise plugin configuration. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - - my $parser ||= XML::DOM::Parser->new(%$args) - || return $class->_throw("failed to create XML::DOM::Parser\n"); - - # we've had to deprecate the old usage because it broke things big time - # with DOM trees never getting cleaned up. - return $class->_throw("XML::DOM usage has changed - you must now call parse()\n") - if @_; - - bless { - _PARSER => $parser, - _DOCS => [ ], - _CONTEXT => $context, - _PREFIX => $args->{ prefix } || '', - _SUFFIX => $args->{ suffix } || '', - _DEFAULT => $args->{ default } || '', - _VERBOSE => $args->{ verbose } || 0, - _NOSPACE => $args->{ nospace } || 0, - _DEEP => $args->{ deep } || 0, - }, $class; -} - - -#------------------------------------------------------------------------ -# parse($content, \%named_params) -# -# Parses an XML stream, provided as the first positional argument (assumed -# to be a filename unless it contains a '<' character) or specified in -# the named parameter hash as one of 'text', 'xml' (same as text), 'file' -# or 'filename'. -#------------------------------------------------------------------------ - -sub parse { - my $self = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my $parser = $self->{ _PARSER }; - my ($content, $about, $method, $doc); - - # determine the input source from a positional parameter (may be a - # filename or XML text if it contains a '<' character) or by using - # named parameters which may specify one of 'file', 'filename', 'text' - # or 'xml' - - if ($content = shift) { - if ($content =~ /\</) { - $about = 'xml text'; - $method = 'parse'; - } - else { - $about = "xml file $content"; - $method = 'parsefile'; - } - } - elsif ($content = $args->{ text } || $args->{ xml }) { - $about = 'xml text'; - $method = 'parse'; - } - elsif ($content = $args->{ file } || $args->{ filename }) { - $about = "xml file $content"; - $method = 'parsefile'; - } - else { - return $self->_throw('no filename or xml text specified'); - } - - # parse the input source using the appropriate method determined above - eval { $doc = $parser->$method($content) } and not $@ - or return $self->_throw("failed to parse $about: $@"); - - # update XML::DOM::Document _UserData to contain config details - $doc->[ XML::DOM::Node::_UserData ] = { - map { ( $_ => $self->{ $_ } ) } - qw( _CONTEXT _PREFIX _SUFFIX _VERBOSE _NOSPACE _DEEP _DEFAULT ), - }; - - # keep track of all DOM docs for subsequent dispose() -# print STDERR "DEBUG: $self adding doc: $doc\n" -# if $DEBUG; - - push(@{ $self->{ _DOCS } }, $doc); - - return $doc; -} - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raised a Template::Exception of type XML.DOM via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; - die (Template::Exception->new('XML.DOM', $error)); -} - - -#------------------------------------------------------------------------ -# DESTROY -# -# Cleanup method which calls dispose() on any and all DOM documents -# created by this object. Also breaks any circular references that -# may exist with the context object. -#------------------------------------------------------------------------ - -sub DESTROY { - my $self = shift; - - # call dispose() on each document produced by this parser - foreach my $doc (@{ $self->{ _DOCS } }) { -# print STDERR "DEBUG: $self destroying $doc\n" -# if $DEBUG; - if (ref $doc) { -# print STDERR "disposing of $doc\n"; - undef $doc->[ XML::DOM::Node::_UserData ]->{ _CONTEXT }; - $doc->dispose(); - } - } - delete $self->{ _CONTEXT }; - delete $self->{ _PARSER }; -} - - - -#======================================================================== -package XML::DOM::Node; -#======================================================================== - - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present node via a view (supercedes all that messy toTemplate -# stuff below). -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - - if ($self->getNodeType() == XML::DOM::ELEMENT_NODE) { - # it's an element - $view->view($self->getTagName(), $self); - } - else { - my $text = $self->toString(); - $view->view('text', $text); - } -} - -sub content { - my ($self, $view) = @_; - my $output = ''; - foreach my $node (@{ $self->getChildNodes }) { - $output .= $node->present($view); - -# abw test passing args, Aug 2001 -# $output .= $view->print($node); - } - return $output; -} - - -#------------------------------------------------------------------------ -# toTemplate($prefix, $suffix, \%named_params) -# -# Process the current node as a template. -#------------------------------------------------------------------------ - -sub toTemplate { - my $self = shift; - _template_node($self, $self->_args(@_)); -} - - -#------------------------------------------------------------------------ -# childrenToTemplate($prefix, $suffix, \%named_params) -# -# Process all the current node's children as templates. -#------------------------------------------------------------------------ - -sub childrenToTemplate { - my $self = shift; - _template_kids($self, $self->_args(@_)); -} - - -#------------------------------------------------------------------------ -# allChildrenToTemplate($prefix, $suffix, \%named_params) -# -# Process all the current node's children, and their children, and -# their children, etc., etc., as templates. Same effect as calling the -# childrenToTemplate() method with the 'deep' option set. -#------------------------------------------------------------------------ - -sub allChildrenToTemplate { - my $self = shift; - my $args = $self->_args(@_); - $args->{ deep } = 1; - _template_kids($self, $args); -} - - -#------------------------------------------------------------------------ -# _args($prefix, $suffix, \%name_params) -# -# Reads the optional positional parameters, $prefix and $suffix, and -# also examines any named parameters hash to construct a set of -# current configuration parameters. Where not specified directly, the -# object defaults are used. -#------------------------------------------------------------------------ - -sub _args { - my $self = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my $doc = $self->getOwnerDocument() || $self; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - return { - prefix => @_ ? shift : $args->{ prefix } || $data->{ _PREFIX }, - suffix => @_ ? shift : $args->{ suffix } || $data->{ _SUFFIX }, - verbose => $args->{ verbose } || $data->{ _VERBOSE }, - nospace => $args->{ nospace } || $data->{ _NOSPACE }, - deep => $args->{ deep } || $data->{ _DEEP }, - default => $args->{ default } || $data->{ _DEFAULT }, - context => $data->{ _CONTEXT }, - }; -} - - - -#------------------------------------------------------------------------ -# _template_node($node, $args, $vars) -# -# Process a template for the current DOM node where the template name -# is taken from the node TagName, with any specified 'prefix' and/or -# 'suffix' applied. The 'default' argument can also be provided to -# specify a default template to be used when a specific template can't -# be found. The $args parameter referenced a hash array through which -# these configuration items are passed (see _args()). The current DOM -# node is made available to the template as the variable 'node', along -# with any other variables passed in the optional $vars hash reference. -# To permit the 'children' and 'prune' callbacks to be raised as node -# methods (see _template_kids() below), these items, if defined in the -# $vars hash, are copied into the node object where its AUTOLOAD method -# can find them. -#------------------------------------------------------------------------ - -sub _template_node { - my $node = shift || die "no XML::DOM::Node reference\n"; - my $args = shift || die "no XML::DOM args passed to _template_node\n"; - my $vars = shift || { }; - my $context = $args->{ context } || die "no context in XML::DOM args\n"; - my $template; - my $output = ''; - - # if this is not an element then it is text so output it - unless ($node->getNodeType() == XML::DOM::ELEMENT_NODE ) { - if ($args->{ verbose }) { - $output = $node->toString(); - $output =~ s/\s+$// if $args->{ nospace }; - } - } - else { - my $element = ( $args->{ prefix } || '' ) - . $node->getTagName() - . ( $args->{ suffix } || '' ); - - # locate a template by name built from prefix, tagname and suffix - # or fall back on any default template specified - eval { $template = $context->template($element) }; - eval { $template = $context->template($args->{ default }) } - if $@ && $args->{ default }; - $template = $element unless $template; - - # copy 'children' and 'prune' callbacks into node object (see AUTOLOAD) - my $doc = $node->getOwnerDocument() || $node; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - $data->{ _TT_CHILDREN } = $vars->{ children }; - $data->{ _TT_PRUNE } = $vars->{ prune }; - - # add node reference to existing vars hash - $vars->{ node } = $node; - - $output = $context->include($template, $vars); - - # break any circular references - delete $vars->{ node }; - delete $data->{ _TT_CHILDREN }; - delete $data->{ _TT_PRUNE }; - } - - return $output; -} - - -#------------------------------------------------------------------------ -# _template_kids($node, $args) -# -# Process all the children of the current node as templates, via calls -# to _template_node(). If the 'deep' argument is set, then the process -# will continue recursively. In this case, the node template is first -# processed, followed by any children of that node (i.e. depth first, -# parent before). A closure called 'children' is created and added -# to the Stash variables passed to _template_node(). This can be called -# from the parent template to process all child nodes at the current point. -# This then "prunes" the tree preventing the children from being processed -# after the parent template. A 'prune' callback is also added to prune -# the tree without processing the children. Note that _template_node() -# copies these callbacks into each parent node, allowing them to be called -# as [% node. -#------------------------------------------------------------------------ - -sub _template_kids { - my $node = shift || die "no XML::DOM::Node reference\n"; - my $args = shift || die "no XML::DOM args passed to _template_kids\n"; - my $context = $args->{ context } || die "no context in XML::DOM args\n"; - my $output = ''; - - foreach my $kid ( $node->getChildNodes() ) { - # define some callbacks to allow template to call [% content %] - # or [% prune %]. They are also inserted into each node reference - # so they can be called as [% node.content %] and [% node.prune %] - my $prune = 0; - my $vars = { }; - $vars->{ children } = sub { - $prune = 1; - _template_kids($kid, $args); - }; - $vars->{ prune } = sub { - $prune = 1; - return ''; - }; - - $output .= _template_node($kid, $args, $vars); - $output .= _template_kids($kid, $args) - if $args->{ deep } && ! $prune; - } - return $output; -} - - -#======================================================================== -package XML::DOM::Element; -#======================================================================== - -use vars qw( $AUTOLOAD ); - -sub AUTOLOAD { - my $self = shift; - my $method = $AUTOLOAD; - my $attrib; - - $method =~ s/.*:://; - return if $method eq 'DESTROY'; - - my $doc = $self->getOwnerDocument() || $self; - my $data = $doc->[ XML::DOM::Node::_UserData ]; - - # call 'content' or 'prune' callbacks, if defined (see _template_node()) - return &$attrib() - if ($method =~ /^children|prune$/) - && defined($attrib = $data->{ "_TT_\U$method" }) - && ref $attrib eq 'CODE'; - - return $attrib - if defined ($attrib = $self->getAttribute($method)); - - return ''; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::DOM - Plugin interface to XML::DOM - -=head1 SYNOPSIS - - # load plugin - [% USE dom = XML.DOM %] - - # also provide XML::Parser options - [% USE dom = XML.DOM(ProtocolEncoding =E<gt> 'ISO-8859-1') %] - - # parse an XML file - [% doc = dom.parse(filename) %] - [% doc = dom.parse(file => filename) %] - - # parse XML text - [% doc = dom.parse(xmltext) %] - [% doc = dom.parse(text => xmltext) %] - - # call any XML::DOM methods on document/element nodes - [% FOREACH node = doc.getElementsByTagName('report') %] - * [% node.getAttribute('title') %] # or just '[% node.title %]' - [% END %] - - # define VIEW to present node(s) - [% VIEW report notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.title %]</h1> - [% item.content(view) %] - [% END %] - - # default template block converts item to string representation - [% BLOCK xmlstring; item.toString; END %] - - # block to generate simple text - [% BLOCK text; item; END %] - [% END %] - - # now present node (and children) via view - [% report.print(node) %] - - # or print node content via view - [% node.content(report) %] - - # following methods are soon to be deprecated in favour of views - [% node.toTemplate %] - [% node.childrenToTemplate %] - [% node.allChildrenToTemplate %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser (2.19 or later) and XML::DOM -(1.27 or later) modules be installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -Note that the XML::DOM module is now distributed as part of the -'libxml-enno' bundle. - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::DOM module. -The plugin loads the XML::DOM module and creates an XML::DOM::Parser -object which is stored internally. The parse() method can then be -called on the plugin to parse an XML stream into a DOM document. - - [% USE dom = XML.DOM %] - [% doc = dom.parse('/tmp/myxmlfile') %] - -NOTE: earlier versions of this XML::DOM plugin expected a filename to -be passed as an argument to the constructor. This is no longer -supported due to the fact that it caused a serious memory leak. We -apologise for the inconvenience but must insist that you change your -templates as shown: - - # OLD STYLE: now fails with a warning - [% USE dom = XML.DOM('tmp/myxmlfile') %] - - # NEW STYLE: do this instead - [% USE dom = XML.DOM %] - [% doc = dom.parse('tmp/myxmlfile') %] - -The root of the problem lies in XML::DOM creating massive circular -references in the object models it constructs. The dispose() method -must be called on each document to release the memory that it would -otherwise hold indefinately. The XML::DOM plugin object (i.e. 'dom' -in these examples) acts as a sentinel for the documents it creates -('doc' and any others). When the plugin object goes out of scope at -the end of the current template, it will automatically call dispose() -on any documents that it has created. Note that if you dispose of the -the plugin object before the end of the block (i.e. by assigning a -new value to the 'dom' variable) then the documents will also be -disposed at that point and should not be used thereafter. - - [% USE dom = XML.DOM %] - [% doc = dom.parse('/tmp/myfile') %] - [% dom = 'new value' %] # releases XML.DOM plugin and calls - # dispose() on 'doc', so don't use it! - -Any template processing parameters (see toTemplate() method and -friends, below) can be specified with the constructor and will be used -to define defaults for the object. - - [% USE dom = XML.DOM(prefix => 'theme1/') %] - -The plugin constructor will also accept configuration options destined -for the XML::Parser object: - - [% USE dom = XML.DOM(ProtocolEncoding => 'ISO-8859-1') %] - -=head1 METHODS - -=head2 parse() - -The parse() method accepts a positional parameter which contains a filename -or XML string. It is assumed to be a filename unless it contains a E<lt> -character. - - [% xmlfile = '/tmp/foo.xml' %] - [% doc = dom.parse(xmlfile) %] - - [% xmltext = BLOCK %] - <xml> - <blah><etc/></blah> - ... - </xml> - [% END %] - [% doc = dom.parse(xmltext) %] - -The named parameters 'file' (or 'filename') and 'text' (or 'xml') can also -be used: - - [% doc = dom.parse(file = xmlfile) %] - [% doc = dom.parse(text = xmltext) %] - -The parse() method returns an instance of the XML::DOM::Document object -representing the parsed document in DOM form. You can then call any -XML::DOM methods on the document node and other nodes that its methods -may return. See L<XML::DOM> for full details. - - [% FOREACH node = doc.getElementsByTagName('CODEBASE') %] - * [% node.getAttribute('href') %] - [% END %] - -This plugin also provides an AUTOLOAD method for XML::DOM::Node which -calls getAttribute() for any undefined methods. Thus, you can use the -short form of - - [% node.attrib %] - -in place of - - [% node.getAttribute('attrib') %] - -=head2 toTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -This method will process a template for the current node on which it is -called. The template name is constructed from the node TagName with any -optional 'prefix' and/or 'suffix' options applied. A 'default' template -can be named to be used when the specific template cannot be found. The -node object is available to the template as the 'node' variable. - -Thus, for this XML fragment: - - <page title="Hello World!"> - ... - </page> - -and this template definition: - - [% BLOCK page %] - Page: [% node.title %] - [% END %] - -the output of calling toTemplate() on the E<lt>pageE<gt> node would be: - - Page: Hello World! - -=head2 childrenToTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -Effectively calls toTemplate() for the current node and then for each of -the node's children. By default, the parent template is processed first, -followed by each of the children. The 'children' closure can be called -from within the parent template to have them processed and output -at that point. This then suppresses the children from being processed -after the parent template. - -Thus, for this XML fragment: - - <foo> - <bar id="1"/> - <bar id="2"/> - </foo> - -and these template definitions: - - [% BLOCK foo %] - start of foo - end of foo - [% END %] - - [% BLOCK bar %] - bar [% node.id %] - [% END %] - -the output of calling childrenToTemplate() on the parent E<lt>fooE<gt> node -would be: - - start of foo - end of foo - bar 1 - bar 2 - -Adding a call to [% children %] in the 'foo' template: - - [% BLOCK foo %] - start of foo - [% children %] - end of foo - [% END %] - -then creates output as: - - start of foo - bar 1 - bar 2 - end of foo - -The 'children' closure can also be called as a method of the node, if you -prefer: - - [% BLOCK foo %] - start of foo - [% node.children %] - end of foo - [% END %] - -The 'prune' closure is also defined and can be called as [% prune %] or -[% node.prune %]. It prunes the currrent node, preventing any descendants -from being further processed. - - [% BLOCK anynode %] - [% node.toString; node.prune %] - [% END %] - -=head2 allChildrenToTemplate() - -B<NOTE: This method will soon be deprecated in favour of the VIEW based -approach desribed below.> - -Similar to childrenToTemplate() but processing all descendants (i.e. children -of children and so on) recursively. This is identical to calling the -childrenToTemplate() method with the 'deep' flag set to any true value. - -=head1 PRESENTING DOM NODES USING VIEWS - -You can define a VIEW to present all or part of a DOM tree by automatically -mapping elements onto templates. Consider a source document like the -following: - - <report> - <section title="Introduction"> - <p> - Blah blah. - <ul> - <li>Item 1</li> - <li>item 2</li> - </ul> - </p> - </section> - <section title="The Gory Details"> - ... - </section> - </report> - -We can load it up via the XML::DOM plugin and fetch the node for the -E<lt>reportE<gt> element. - - [% USE dom = XML.DOM; - doc = dom.parse(file => filename); - report = doc.getElementsByTagName('report') - %] - -We can then define a VIEW as follows to present this document fragment in -a particular way. The L<Template::Manual::Views> documentation -contains further details on the VIEW directive and various configuration -options it supports. - - [% VIEW report_view notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.title %]</h1> - [% item.content(view) %] - [% END %] - - # default template block converts item to string representation - [% BLOCK xmlstring; item.toString; END %] - - # block to generate simple text - [% BLOCK text; item; END %] - [% END %] - -Each BLOCK defined within the VIEW represents a presentation style for -a particular element or elements. The current node is available via the -'item' variable. Elements that contain other content can generate it -according to the current view by calling [% item.content(view) %]. -Elements that don't have a specific template defined are mapped to the -'xmlstring' template via the 'notfound' parameter specified in the VIEW -header. This replicates the node as an XML string, effectively allowing -general XML/XHTML markup to be passed through unmodified. - -To present the report node via the view, we simply call: - - [% report_view.print(report) %] - -The output from the above example would look something like this: - - <h1>Introduction</h1> - <p> - Blah blah. - <ul> - <li>Item 1</li> - <li>item 2</li> - </ul> - </p> - - <h1>The Gory Details</h1> - ... - -To print just the content of the report node (i.e. don't process the -'report' template for the report node), you can call: - - [% report.content(report_view) %] - -=head1 AUTHORS - -This plugin module was written by Andy Wardley E<lt>abw@wardley.orgE<gt> -and Simon Matthews E<lt>sam@knowledgepool.comE<gt>. - -The XML::DOM module is by Enno Derksen E<lt>enno@att.comE<gt> and Clark -Cooper E<lt>coopercl@sch.ge.comE<gt>. It extends the the XML::Parser -module, also by Clark Cooper which itself is built on James Clark's expat -library. - -=head1 VERSION - -2.6, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - - - -=head1 HISTORY - -Version 2.5 : updated for use with version 1.27 of the XML::DOM module. - -=over 4 - -=item * - -XML::DOM 1.27 now uses array references as the underlying data type -for DOM nodes instead of hash array references. User data is now -bound to the _UserData node entry instead of being forced directly -into the node hash. - -=back - -=head1 BUGS - -The childrenToTemplate() and allChildrenToTemplate() methods can easily -slip into deep recursion. - -The 'verbose' and 'nospace' options are not documented. They may -change in the near future. - -=head1 COPYRIGHT - -Copyright (C) 2000-2001 Andy Wardley, Simon Matthews. All Rights Reserved. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::DOM|XML::DOM>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/RSS.pm b/lib/Template/Plugin/XML/RSS.pm deleted file mode 100644 index 32da7d8..0000000 --- a/lib/Template/Plugin/XML/RSS.pm +++ /dev/null @@ -1,194 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::RSS -# -# DESCRIPTION -# -# Template Toolkit plugin which interfaces to Jonathan Eisenzopf's XML::RSS -# module. RSS is the Rich Site Summary format. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 Andy Wardley. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: RSS.pm,v 2.64 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::RSS; - -require 5.004; - -use strict; -use vars qw( $VERSION ); -use base qw( Template::Plugin ); -use Template::Plugin; -use XML::RSS; - -$VERSION = sprintf("%d.%02d", q$Revision: 2.64 $ =~ /(\d+)\.(\d+)/); - -sub load { - return $_[0]; -} - -sub new { - my ($class, $context, $filename) = @_; - - return $class->fail('No filename specified') - unless $filename; - - my $rss = XML::RSS->new - or return $class->fail('failed to create XML::RSS'); - - # Attempt to determine if $filename is an XML string or - # a filename. Based on code from the XML.XPath plugin. - eval { - if ($filename =~ /\</) { - $rss->parse($filename); - } - else { - $rss->parsefile($filename) - } - } and not $@ - or return $class->fail("failed to parse $filename: $@"); - - return $rss; -} - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::RSS - Plugin interface to XML::RSS - -=head1 SYNOPSIS - - [% USE news = XML.RSS($filename) %] - - [% FOREACH item = news.items %] - [% item.title %] - [% item.link %] - [% END %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::RSS modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 DESCRIPTION - -This Template Toolkit plugin provides a simple interface to the -XML::RSS module. - - [% USE news = XML.RSS('mysite.rdf') %] - -It creates an XML::RSS object, which is then used to parse the RSS -file specified as a parameter in the USE directive. A reference to -the XML::RSS object is then returned. - -An RSS (Rich Site Summary) file is typically used to store short news -'headlines' describing different links within a site. This example is -extracted from http://slashdot.org/slashdot.rdf. - - <?xml version="1.0"?><rdf:RDF - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns="http://my.netscape.com/rdf/simple/0.9/"> - - <channel> - <title>Slashdot:News for Nerds. Stuff that Matters.</title> - <link>http://slashdot.org</link> - <description>News for Nerds. Stuff that Matters</description> - </channel> - - <image> - <title>Slashdot</title> - <url>http://slashdot.org/images/slashdotlg.gif</url> - <link>http://slashdot.org</link> - </image> - - <item> - <title>DVD CCA Battle Continues Next Week</title> - <link>http://slashdot.org/article.pl?sid=00/01/12/2051208</link> - </item> - - <item> - <title>Matrox to fund DRI Development</title> - <link>http://slashdot.org/article.pl?sid=00/01/13/0718219</link> - </item> - - <item> - <title>Mike Shaver Leaving Netscape</title> - <link>http://slashdot.org/article.pl?sid=00/01/13/0711258</link> - </item> - - </rdf:RDF> - -The attributes of the channel and image elements can be retrieved directly -from the plugin object using the familiar dotted compound notation: - - [% news.channel.title %] - [% news.channel.link %] - [% news.channel.etc... %] - - [% news.image.title %] - [% news.image.url %] - [% news.image.link %] - [% news.image.etc... %] - -The list of news items can be retrieved using the 'items' method: - - [% FOREACH item = news.items %] - [% item.title %] - [% item.link %] - [% END %] - -=head1 AUTHORS - -This plugin was written by Andy Wardley E<lt>abw@wardley.orgE<gt>, -inspired by an article in Web Techniques by Randal Schwartz -E<lt>merlyn@stonehenge.comE<gt>. - -The XML::RSS module, which implements all of the functionality that -this plugin delegates to, was written by Jonathan Eisenzopf -E<lt>eisen@pobox.comE<gt>. - -=head1 VERSION - -2.64, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 Canon Research Centre Europe Ltd. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::RSS|XML::RSS>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/Simple.pm b/lib/Template/Plugin/XML/Simple.pm deleted file mode 100644 index aaa4479..0000000 --- a/lib/Template/Plugin/XML/Simple.pm +++ /dev/null @@ -1,124 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::Simple -# -# DESCRIPTION -# Template Toolkit plugin interfacing to the XML::Simple.pm module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 Andy Wardley. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: Simple.pm,v 2.63 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::Simple; - -require 5.004; - -use strict; -use Template::Plugin; -use XML::Simple; - -use base qw( Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.63 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, $file_or_text, \%config) -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $input = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - - XMLin($input, %$args); -} - - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raise a Template::Exception of type XML.Simple via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; - die (Template::Exception->new('XML.Simple', $error)); -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::Simple - Plugin interface to XML::Simple - -=head1 SYNOPSIS - - # load plugin and specify XML file to parse - [% USE xml = XML.Simple(xml_file_or_text) %] - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::Simple module. - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::Simple modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 AUTHORS - -This plugin wrapper module was written by Andy Wardley -E<lt>abw@wardley.orgE<gt>. - -The XML::Simple module which implements all the core functionality -was written by Grant McLean E<lt>grantm@web.co.nzE<gt>. - -=head1 VERSION - -2.63, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 Canon Research Centre Europe Ltd. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::Simple|XML::Simple>, L<XML::Parser|XML::Parser> - diff --git a/lib/Template/Plugin/XML/Style.pm b/lib/Template/Plugin/XML/Style.pm deleted file mode 100644 index 7613f2f..0000000 --- a/lib/Template/Plugin/XML/Style.pm +++ /dev/null @@ -1,357 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::Style -# -# DESCRIPTION -# Template Toolkit plugin which performs some basic munging of XML -# to perform simple stylesheet like transformations. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2001 Andy Wardley. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -# REVISION -# $Id: Style.pm,v 2.34 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::Style; - -require 5.004; - -use strict; -use Template::Plugin::Filter; - -use base qw( Template::Plugin::Filter ); -use vars qw( $VERSION $DYNAMIC $FILTER_NAME ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.34 $ =~ /(\d+)\.(\d+)/); -$DYNAMIC = 1; -$FILTER_NAME = 'xmlstyle'; - - -#------------------------------------------------------------------------ -# new($context, \%config) -#------------------------------------------------------------------------ - -sub init { - my $self = shift; - my $name = $self->{ _ARGS }->[0] || $FILTER_NAME; - $self->install_filter($name); - return $self; -} - - -sub filter { - my ($self, $text, $args, $config) = @_; - - # munge start tags - $text =~ s/ < ([\w\.\:]+) ( \s+ [^>]+ )? > - / $self->start_tag($1, $2, $config) - /gsex; - - # munge end tags - $text =~ s/ < \/ ([\w\.\:]+) > - / $self->end_tag($1, $config) - /gsex; - - return $text; - -} - - -sub start_tag { - my ($self, $elem, $textattr, $config) = @_; - $textattr ||= ''; - my ($pre, $post); - - # look for an element match in the stylesheet - my $match = $config->{ $elem } - || $self->{ _CONFIG }->{ $elem } - || return "<$elem$textattr>"; - - # merge element attributes into copy of stylesheet attributes - my $attr = { %{ $match->{ attributes } || { } } }; - while ($textattr =~ / \s* ([\w\.\:]+) = " ([^"]+) " /gsx ) { - $attr->{ $1 } = $2; - } - $textattr = join(' ', map { "$_=\"$attr->{$_}\"" } keys %$attr); - $textattr = " $textattr" if $textattr; - - $elem = $match->{ element } || $elem; - $pre = $match->{ pre_start } || ''; - $post = $match->{ post_start } || ''; - - return "$pre<$elem$textattr>$post"; -} - - -sub end_tag { - my ($self, $elem, $config) = @_; - my ($pre, $post); - - # look for an element match in the stylesheet - my $match = $config->{ $elem } - || $self->{ _CONFIG }->{ $elem } - || return "</$elem>"; - - $elem = $match->{ element } || $elem; - $pre = $match->{ pre_end } || ''; - $post = $match->{ post_end } || ''; - - return "$pre</$elem>$post"; -} - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::Style - Simple XML stylesheet transfomations - -=head1 SYNOPSIS - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - cellspacing = 1 - } - } - %] - - [% FILTER xmlstyle %] - <table> - <tr> - <td>Foo</td> <td>Bar</td> <td>Baz</td> - </tr> - </table> - [% END %] - -=head1 DESCRIPTION - -This plugin defines a filter for performing simple stylesheet based -transformations of XML text. - -Named parameters are used to define those XML elements which require -transformation. These may be specified with the USE directive when -the plugin is loaded and/or with the FILTER directive when the plugin -is used. - -This example shows how the default attributes C<border="0"> and -C<cellpadding="4"> can be added to E<lt>tableE<gt> elements. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - } - } - %] - - [% FILTER xmlstyle %] - <table> - ... - </table> - [% END %] - -This produces the output: - - <table border="0" cellpadding="4"> - ... - </table> - -Parameters specified within the USE directive are applied automatically each -time the C<xmlstyle> FILTER is used. Additional parameters passed to the -FILTER directive apply for only that block. - - [% USE xmlstyle - table = { - attributes = { - border = 0 - cellpadding = 4 - } - } - %] - - [% FILTER xmlstyle - tr = { - attributes = { - valign="top" - } - } - %] - <table> - <tr> - ... - </tr> - </table> - [% END %] - -Of course, you may prefer to define your stylesheet structures once and -simply reference them by name. Passing a hash reference of named parameters -is just the same as specifying the named parameters as far as the Template -Toolkit is concerned. - - [% style_one = { - table = { ... } - tr = { ... } - } - style_two = { - table = { ... } - td = { ... } - } - style_three = { - th = { ... } - tv = { ... } - } - %] - - [% USE xmlstyle style_one %] - - [% FILTER xmlstyle style_two %] - # style_one and style_two applied here - [% END %] - - [% FILTER xmlstyle style_three %] - # style_one and style_three applied here - [% END %] - -Any attributes defined within the source tags will override those specified -in the style sheet. - - [% USE xmlstyle - div = { attributes = { align = 'left' } } - %] - - - [% FILTER xmlstyle %] - <div>foo</div> - <div align="right">bar</div> - [% END %] - -The output produced is: - - <div align="left">foo</div> - <div align="right">bar</div> - -The filter can also be used to change the element from one type to another. - - [% FILTER xmlstyle - th = { - element = 'td' - attributes = { bgcolor='red' } - } - %] - <tr> - <th>Heading</th> - </tr> - <tr> - <td>Value</td> - </tr> - [% END %] - -The output here is as follows. Notice how the end tag C<E<lt>/thE<gt>> is -changed to C<E<lt>/tdE<gt>> as well as the start tag. - - <tr> - <td bgcolor="red">Heading</td> - </tr> - <tr> - <td>Value</td> - </tr> - -You can also define text to be added immediately before or after the -start or end tags. For example: - - [% FILTER xmlstyle - table = { - pre_start = '<div align="center">' - post_end = '</div>' - } - th = { - element = 'td' - attributes = { bgcolor='red' } - post_start = '<b>' - pre_end = '</b>' - } - %] - <table> - <tr> - <th>Heading</th> - </tr> - <tr> - <td>Value</td> - </tr> - </table> - [% END %] - -The output produced is: - - <div align="center"> - <table> - <tr> - <td bgcolor="red"><b>Heading</b></td> - </tr> - <tr> - <td>Value</td> - </tr> - </table> - </div> - -=head1 AUTHOR - -Andy Wardley E<lt>abw@andywardley.comE<gt> - -L<http://www.andywardley.com/|http://www.andywardley.com/> - - - - -=head1 VERSION - -2.34, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 Canon Research Centre Europe Ltd. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin> - -=cut - -# Local Variables: -# mode: perl -# perl-indent-level: 4 -# indent-tabs-mode: nil -# End: -# -# vim: expandtab shiftwidth=4: diff --git a/lib/Template/Plugin/XML/XPath.pm b/lib/Template/Plugin/XML/XPath.pm deleted file mode 100644 index adf9292..0000000 --- a/lib/Template/Plugin/XML/XPath.pm +++ /dev/null @@ -1,284 +0,0 @@ -#============================================================= -*-Perl-*- -# -# Template::Plugin::XML::XPath -# -# DESCRIPTION -# -# Template Toolkit plugin interfacing to the XML::XPath.pm module. -# -# AUTHOR -# Andy Wardley <abw@kfs.org> -# -# COPYRIGHT -# Copyright (C) 2000 Andy Wardley. All Rights Reserved. -# -# This module is free software; you can redistribute it and/or -# modify it under the same terms as Perl itself. -# -#---------------------------------------------------------------------------- -# -# $Id: XPath.pm,v 2.69 2004/01/13 16:21:50 abw Exp $ -# -#============================================================================ - -package Template::Plugin::XML::XPath; - -require 5.004; - -use strict; -use Template::Exception; -use Template::Plugin; -use XML::XPath; - -use base qw( Template::Plugin ); -use vars qw( $VERSION ); - -$VERSION = sprintf("%d.%02d", q$Revision: 2.69 $ =~ /(\d+)\.(\d+)/); - - -#------------------------------------------------------------------------ -# new($context, \%config) -# -# Constructor method for XML::XPath plugin. Creates an XML::XPath -# object and initialises plugin configuration. -#------------------------------------------------------------------------ - -sub new { - my $class = shift; - my $context = shift; - my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { }; - my ($content, $about); - - # determine the input source from a positional parameter (may be a - # filename or XML text if it contains a '<' character) or by using - # named parameters which may specify one of 'file', 'filename', 'text' - # or 'xml' - - if ($content = shift) { - if ($content =~ /\</) { - $about = 'xml text'; - $args->{ xml } = $content; - } - else { - $about = "xml file $content"; - $args->{ filename } = $content; - } - } - elsif ($content = $args->{ text } || $args->{ xml }) { - $about = 'xml text'; - $args->{ xml } = $content; - } - elsif ($content = $args->{ file } || $args->{ filename }) { - $about = "xml file $content"; - $args->{ filename } = $content; - } - else { - return $class->_throw('no filename or xml text specified'); - } - - return XML::XPath->new(%$args) - or $class->_throw("failed to create XML::XPath::Parser\n"); -} - - - -#------------------------------------------------------------------------ -# _throw($errmsg) -# -# Raise a Template::Exception of type XML.XPath via die(). -#------------------------------------------------------------------------ - -sub _throw { - my ($self, $error) = @_; -# print STDERR "about to throw $error\n"; - die (Template::Exception->new('XML.XPath', $error)); -} - - -#======================================================================== -package XML::XPath::Node::Element; -#======================================================================== - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present an element node via a view. -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view($self->getName(), $self); -} - -sub content { - my ($self, $view) = @_; - my $output = ''; - foreach my $node (@{ $self->getChildNodes }) { - $output .= $node->present($view); - } - return $output; -} - -#---------------------------------------------------------------------- -# starttag(), endtag() -# -# Methods to output the start & end tag, e.g. <foo bar="baz"> & </foo> -#---------------------------------------------------------------------- - -sub starttag { - my ($self) = @_; - my $output = "<". $self->getName(); - foreach my $attr ($self->getAttributes()) - { - $output .= $attr->toString(); - } - $output .= ">"; - return $output; -} - -sub endtag { - my ($self) = @_; - return "</". $self->getName() . ">"; -} - -#======================================================================== -package XML::XPath::Node::Text; -#======================================================================== - -#------------------------------------------------------------------------ -# present($view) -# -# Method to present a text node via a view. -#------------------------------------------------------------------------ - -sub present { - my ($self, $view) = @_; - $view->view('text', $self->string_value); -} - - -#======================================================================== -package XML::XPath::Node::Comment; -#======================================================================== - -sub present { return ''; } -sub starttag { return ''; } -sub endtag { return ''; } - - -1; - -__END__ - - -#------------------------------------------------------------------------ -# IMPORTANT NOTE -# This documentation is generated automatically from source -# templates. Any changes you make here may be lost. -# -# The 'docsrc' documentation source bundle is available for download -# from http://www.template-toolkit.org/docs.html and contains all -# the source templates, XML files, scripts, etc., from which the -# documentation for the Template Toolkit is built. -#------------------------------------------------------------------------ - -=head1 NAME - -Template::Plugin::XML::XPath - Plugin interface to XML::XPath - -=head1 SYNOPSIS - - # load plugin and specify XML file to parse - [% USE xpath = XML.XPath(xmlfile) %] - [% USE xpath = XML.XPath(file => xmlfile) %] - [% USE xpath = XML.XPath(filename => xmlfile) %] - - # load plugin and specify XML text to parse - [% USE xpath = XML.XPath(xmltext) %] - [% USE xpath = XML.XPath(xml => xmltext) %] - [% USE xpath = XML.XPath(text => xmltext) %] - - # then call any XPath methods (see XML::XPath docs) - [% FOREACH page = xpath.findnodes('/html/body/page') %] - [% page.getAttribute('title') %] - [% END %] - - # define VIEW to present node(s) - [% VIEW repview notfound='xmlstring' %] - # handler block for a <report>...</report> element - [% BLOCK report %] - [% item.content(view) %] - [% END %] - - # handler block for a <section title="...">...</section> element - [% BLOCK section %] - <h1>[% item.getAttribute('title') | html %]</h1> - [% item.content(view) %] - [% END %] - - # default template block passes tags through and renders - # out the children recursivly - [% BLOCK xmlstring; - item.starttag; item.content(view); item.endtag; - END %] - - # block to generate simple text - [% BLOCK text; item | html; END %] - [% END %] - - # now present node (and children) via view - [% repview.print(page) %] - - # or print node content via view - [% page.content(repview) %] - -=head1 PRE-REQUISITES - -This plugin requires that the XML::Parser and XML::XPath modules be -installed. These are available from CPAN: - - http://www.cpan.org/modules/by-module/XML - -=head1 DESCRIPTION - -This is a Template Toolkit plugin interfacing to the XML::XPath module. - -All methods implemented by the XML::XPath modules are available. In -addition, the XML::XPath::Node::Element module implements -present($view) and content($view) methods method for seamless -integration with Template Toolkit VIEWs. The XML::XPath::Node::Text -module is also adorned with a present($view) method which presents -itself via the view using the 'text' template. - -To aid the reconstruction of XML, methods starttag and endtag are -added to XML::XPath::Node::Element which return the start and -end tag for that element. This means that you can easily do: - - [% item.starttag %][% item.content(view) %][% item.endtag %] - -To render out the start tag, followed by the content rendered in the -view "view", followed by the end tag. - -=head1 AUTHORS - -This plugin module was written by Andy Wardley E<lt>abw@wardley.orgE<gt>. - -The XML::XPath module is by Matt Sergeant E<lt>matt@sergeant.orgE<gt>. - -=head1 VERSION - -2.69, distributed as part of the -Template Toolkit version 2.13, released on 30 January 2004. - -=head1 COPYRIGHT - - Copyright (C) 1996-2004 Andy Wardley. All Rights Reserved. - Copyright (C) 1998-2002 Canon Research Centre Europe Ltd. - -This module is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<Template::Plugin|Template::Plugin>, L<XML::XPath|XML::XPath>, L<XML::Parser|XML::Parser> - |
