Template-XML-2.17/ 0000755 0001750 0001750 00000000000 10563116312 013216 5 ustar abw abw 0000000 0000000 Template-XML-2.17/t/ 0000755 0001750 0001750 00000000000 10563116312 013461 5 ustar abw abw 0000000 0000000 Template-XML-2.17/t/xml/ 0000755 0001750 0001750 00000000000 10563116312 014261 5 ustar abw abw 0000000 0000000 Template-XML-2.17/t/xml/example.xml 0000644 0001750 0001750 00000000412 10563113666 016444 0 ustar abw abw 0000000 0000000
Template-XML-2.17/t/test/ 0000755 0001750 0001750 00000000000 10563116312 014440 5 ustar abw abw 0000000 0000000 Template-XML-2.17/t/test/xml/ 0000755 0001750 0001750 00000000000 10563116312 015240 5 ustar abw abw 0000000 0000000 Template-XML-2.17/t/test/xml/testfile.xml 0000644 0001750 0001750 00000000363 10563113666 017614 0 ustar abw abw 0000000 0000000
Template-XML-2.17/t/test/xml/example.rdf 0000644 0001750 0001750 00000001226 10563113666 017402 0 ustar abw abw 0000000 0000000 Template Toolkit XML::RSS Plugin
http://template-toolkit.org/plugins/XML/RSS
The XML::RSS Plugin for the Template ToolkitTest Imagehttp://www.myorg.org/images/test.pngI Read the News Today
http://oh.boy.com/
I am the Walrus
http://goo.goo.ga.joob.org/
Template-XML-2.17/t/xpath.t 0000644 0001750 0001750 00000007716 10563113666 015016 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/xpath.t
#
# Test the XML::XPath plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: xpath.t,v 2.10 2003/04/11 12:28:28 darren Exp $
#
#========================================================================
use strict;
use lib qw( ./lib ../lib );
use Template;
use Template::Test;
use Cwd qw( abs_path );
$^W = 1;
# I hate having to do this
my $shut_up_warnings = $XML::XPath::VERSION;
eval "use XML::XPath";
if ($@ || $XML::XPath::VERSION < 1.0) {
skip_all('XML::XPath v1.0 or later not installed');
}
# account for script being run in distribution root or 't' directory
my $file = abs_path( -d 't' ? 't/test/xml' : 'test/xml' );
$file .= '/testfile.xml';
test_expect(\*DATA, undef, { 'xmlfile' => $file });
__END__
-- test --
[% TRY;
USE xpath = XML.XPath('no_such_file');
xpath.find('/foo/bar');
CATCH;
"ok";
END
%]
-- expect --
ok
-- test --
[% USE xpath = XML.XPath(xmlfile) -%]
[% FOREACH page = xpath.findnodes('/website/section/page') -%]
page: [% page.getAttribute('title') %]
[% END %]
-- expect --
page: The Foo Page
page: The Bar Page
page: The Baz Page
-- test --
[% USE xpath = XML.XPath(file => xmlfile) -%]
[% FOREACH page = xpath.findnodes('/website/section/page') -%]
page: [% page.getAttribute('title') %]
[% END %]
-- expect --
page: The Foo Page
page: The Bar Page
page: The Baz Page
-- test --
[% USE xpath = XML.XPath(filename => xmlfile) -%]
[% FOREACH page = xpath.findnodes('/website/section/page') -%]
page: [% page.getAttribute('title') %]
[% END %]
-- expect --
page: The Foo Page
page: The Bar Page
page: The Baz Page
-- test --
[% xmltext = BLOCK %]
This is the foo section, here is some bold text.
This is the bar section, here is some italic text
[% END -%]
[% USE xpath = XML.XPath(xmltext) -%]
...
[% FOREACH section = xpath.findnodes('/html/body/section') -%]
[% section.string_value %]
[% END %]
-- expect --
...
This is the foo section, here is some bold text.
This is the bar section, here is some italic text
-- test --
[% xmltext = BLOCK -%]
onetwo
[% END -%]
[% VIEW xview notfound='xmlstring' -%]
[% BLOCK foo -%]
FOO {
[%- item.content(view) -%]
}
[% END -%]
[% BLOCK bar -%]
BAR(baz="[% item.getAttribute('baz') %]") {
[%- item.content(view) -%]
}
[% END -%]
[% BLOCK list -%]
LIST:
[%- item.content(view) -%]
[% END -%]
[% BLOCK item -%]
* [% item.content(view) -%]
[% END -%]
[% BLOCK xmlstring; item.toString; END %]
[% BLOCK text; item; END %]
[% END -%]
[%- USE xpath = XML.XPath(xmltext);
foo = xpath.findnodes('/foo');
xview.print(foo);
-%]
-- expect --
FOO {
BAR(baz="10") {
LIST:
* one
* two
}
}
-- test --
[% xmltext = BLOCK -%]
onetwo
[% END -%]
[% VIEW xview notfound='xmlstring' -%]
[% BLOCK item -%]
* [% item.content(view) -%]
[% END -%]
[% BLOCK xmlstring; item.starttag; item.content(view); item.endtag; END %]
[% BLOCK text; item; END %]
[% END -%]
[%- USE xpath = XML.XPath(xmltext);
foo = xpath.findnodes('/foo');
xview.print(foo);
-%]
-- expect --
* one
* two
-- test --
[% xmltext = BLOCK -%]
[% END -%]
[% USE xp = XML.XPath(xml => xmltext);
xp.find("/greeting[@type='hello']/@what") %]
-- expect --
world
-- test --
[% xmltext = BLOCK -%]
world
[% END -%]
[% USE xp = XML.XPath(text => xmltext);
xp.find("/hello"); %]
-- expect --
world
Template-XML-2.17/t/dom.t 0000644 0001750 0001750 00000011347 10563113666 014444 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/dom.t
#
# Test the XML::DOM plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: dom.t,v 2.8 2002/08/12 11:07:14 abw Exp $
#
#========================================================================
use strict;
use warnings;
use lib qw( ./lib ../lib );
use Template;
use Template::Test;
use Template::Plugin::XML;
use Cwd qw( abs_path );
#$Template::Test::DEBUG = 1;
$Template::Test::PRESERVE = 1;
# I hate having to do this
my $shut_up_warnings = $XML::DOM::VERSION;
# make sure we've got XML::DOM installed
eval "use XML::DOM";
skip_all("XML::DOM v1.27 or later not installed")
if $@ || $XML::DOM::VERSION < 1.27;
# disable LibXML
$Template::Plugin::XML::LIBXML = 0;
# account for script being run in distribution root or 't' directory
my $file = abs_path( -d 't' ? 't/test/xml' : 'test/xml' );
$file .= '/testfile.xml';
test_expect(\*DATA, undef, { 'xmlfile' => $file });
__END__
-- test --
-- name: libxml disabled --
[% USE XML;
XML.libxml ? 'error: libxml should be disabled' : 'libxml disabled'
%]
-- expect --
libxml disabled
#------------------------------------------------------------------------
# get XML::DOM via XML plugin
#------------------------------------------------------------------------
-- test --
[% USE XML;
TRY;
file = XML.file(name = 'no_such_file.xml');
dom = file.dom;
CATCH;
error.as_string.replace('(?s::.*)', '');
END
-%]
-- expect --
XML.File error - failed to parse no_such_file.xml
-- test --
[% USE XML;
TRY;
dom = XML.file('no_such_file.xml').dom;
CATCH;
error.as_string.replace('(?s::.*)', '');
END;
-%]
-- expect --
XML.File error - failed to parse no_such_file.xml
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(file => xmlfile) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
#------------------------------------------------------------------------
# get XML::DOM direct via XML.DOM plugin
#------------------------------------------------------------------------
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(xmlfile) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE XML;
dom = XML.dom;
doc = dom.parse(xmlfile)
-%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(file => xmlfile) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(filename => xmlfile) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% global.xmltext = BLOCK %]
Hello World!
[% END -%]
[% USE dom = XML.DOM -%]
[% doc = dom.parse(global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(text => global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(xml => global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
#------------------------------------------------------------------------
# TODO: test views
#------------------------------------------------------------------------
Template-XML-2.17/t/rss.t 0000644 0001750 0001750 00000004430 10563113666 014467 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/rss.t
#
# Test the XML::RSS plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2000 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2000 Canon Research Centre Europe Ltd.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: rss.t,v 2.4 2003/04/11 12:26:03 darren Exp $
#
#========================================================================
use strict;
use lib qw( lib ../lib );
use Template;
use Template::Test;
use Cwd qw( abs_path );
$^W = 1;
# I hate having to do this
my $shut_up_warnings = $XML::RSS::VERSION;
eval "use XML::RSS";
skip_all('XML::RSS v 0.9 or later not installed')
if $@ || ($] == 5.006 && $XML::RSS::VERSION < 0.9);
# account for script being run in distribution root or 't' directory
my $file = abs_path( -d 't' ? 't/test/xml' : 'test/xml' );
$file .= '/example.rdf';
local *RSS;
open RSS, $file or die "Can't open $file: $!";
my $data = join "" => ;
close RSS;
test_expect(\*DATA, undef, { 'newsfile' => $file, 'newsdata' => $data });
__END__
-- test --
[% USE news = XML.RSS(newsfile) -%]
[% FOREACH item = news.items -%]
* [% item.title %]
[% item.link %]
[% END %]
-- expect --
* I Read the News Today
http://oh.boy.com/
* I am the Walrus
http://goo.goo.ga.joob.org/
-- test --
[% USE news = XML.RSS(newsfile) -%]
[% news.channel.title %]
[% news.channel.link %]
-- expect --
Template Toolkit XML::RSS Plugin
http://template-toolkit.org/plugins/XML/RSS
-- test --
[% USE news = XML.RSS(newsfile) -%]
[% news.image.title %]
[% news.image.url %]
-- expect --
Test Image
http://www.myorg.org/images/test.png
-- test --
[% USE news = XML.RSS(newsdata) -%]
[% FOREACH item = news.items -%]
* [% item.title %]
[% item.link %]
[% END %]
-- expect --
* I Read the News Today
http://oh.boy.com/
* I am the Walrus
http://goo.goo.ga.joob.org/
-- test --
[% USE news = XML.RSS(newsdata) -%]
[% news.channel.title %]
[% news.channel.link %]
-- expect --
Template Toolkit XML::RSS Plugin
http://template-toolkit.org/plugins/XML/RSS
-- test --
[% USE news = XML.RSS(newsdata) -%]
[% news.image.title %]
[% news.image.url %]
-- expect --
Test Image
http://www.myorg.org/images/test.png
Template-XML-2.17/t/xml.t 0000644 0001750 0001750 00000021330 10563116254 014452 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/xml.t
#
# Test the XML plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2006 Andy Wardley. All Rights Reserved.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: dom.t,v 2.8 2002/08/12 11:07:14 abw Exp $
#
#========================================================================
use strict;
use warnings;
use lib qw( ./lib ../lib );
use Template;
use Template::Test;
use Cwd qw( abs_path );
my $dir = abs_path( -d 't' ? 't/test/xml' : 'test/xml' );
my $file = 'example.xml';
my $libxml = eval { require XML::LibXML };
my $vars = {
dir => $dir,
file => $file,
libxml => $libxml,
debug_on => sub { $Template::Plugin::XML::DEBUG = 1 },
debug_off => sub { $Template::Plugin::XML::DEBUG = 0 },
libxml_on => sub { $Template::Plugin::XML::LIBXML = 1 },
libxml_off => sub { $Template::Plugin::XML::LIBXML = 0 },
libxml_save => sub { $libxml = $Template::Plugin::XML::LIBXML },
libxml_restore => sub { $Template::Plugin::XML::LIBXML = $libxml },
};
test_expect(\*DATA, undef, $vars);
__END__
#------------------------------------------------------------------------
# test the $DEBUG package variable sets debugging on/off by default
# unless overridden by a debug named parameter
#------------------------------------------------------------------------
-- test --
[% CALL debug_on;
USE XML;
'debugging is '; XML.debug ? 'on' : 'off'
-%]
-- expect --
debugging is on
-- test --
[% CALL debug_off;
USE XML;
'debugging is '; XML.debug ? 'on' : 'off'
-%]
-- expect --
debugging is off
-- test --
[% USE XML(debug=1);
'debugging is '; XML.debug ? 'on' : 'off'
%]
-- expect --
debugging is on
-- test --
[% CALL debug_on;
USE XML(debug=0);
'debugging is '; XML.debug ? 'on' : 'off'
%]
-- expect --
debugging is off
#------------------------------------------------------------------------
# test to see if $LIBXML is defined (if XML::LibXML is available). It
# should match whatever the libxml is set to. Also check that we can
# disable with a parameter and also that we get an error if we try to
# enable it when it's not available.
#------------------------------------------------------------------------
-- test --
[% USE XML;
'libxml is '; XML.libxml ? 'enabled' : 'disabled'
-%]
-- expect --
-- process --
libxml is [% libxml ? 'enabled' : 'disabled' %]
-- test --
[% CALL libxml_off;
USE XML;
'libxml is '; XML.libxml ? 'enabled' : 'disabled';
-%]
-- expect --
libxml is disabled
-- test --
[% USE XML(libxml = 0);
'libxml is '; XML.libxml ? 'enabled' : 'disabled'
-%]
-- expect --
libxml is disabled
-- test --
[% CALL libxml_off;
TRY;
USE XML(libxml=1);
"should have got 'XML::LibXML not available' error but didn't";
CATCH;
"good, we got an error: $error";
END
-%]
-- expect --
good, we got an error: XML error - XML::LibXML is not available
# if libxml is available then check we can set and get various options
# such as expand_entities
-- test --
[% IF libxml;
CALL libxml_restore;
USE XML(expand_entities=1);
"expanding: $XML.libxml.expand_entities\n";
CALL XML.libxml.expand_entities(0);
"expanding: $XML.libxml.expand_entities\n";
ELSE;
"no libxml";
END
-%]
-- expect --
-- process --
[% IF libxml -%]
expanding: 1
expanding: 0
[% ELSE -%]
no libxml
[% END %]
-- stop --
-- test --
[% USE XML(file='xmlfile.xml') -%]
[% XML.type %]: [% XML.source %]
-- expect --
file: xmlfile.xml
-- test --
[% USE XML %]
got libxml? [% XML.libxml ? 'yes' : 'no' %]
-- expect --
-- process --
Hmmm: [% libxml ? 'yes' : 'no' %]
-- stop --
# load a file via the file() method
-- test --
[% USE XML;
xfile = XML.file(file);
xfile.name # a Template::Plugin::XML::File object
-%]
-- expect --
-- process --
[% file %]
-- stop --
-- test --
[% USE XML;
XML.type or 'No type';
%]
-- expect --
No type
# specify directory as constructor parameter
-- test --
[% USE XML( dir => dir );
xfile = XML.file(file);
-%]
name: [% xfile.name %]
dir: [% xfile.dir %]
-- expect --
-- process --
name: [% file %]
dir: [% dir %]
# specify directory via dir() method
-- test --
[% USE XML;
xdir = XML.dir(dir); # Template::Plugin::XML::Directory
xfile = XML.file(file);
-%]
path: [% xdir.path %]
name: [% xfile.name %]
dir: [% xfile.dir %]
-- expect --
-- process --
path: [% dir %]
name: [% file %]
dir: [% dir %]
# specify file via single argument to constructor method
-- test --
[% USE xfile = XML(file) -%]
name: [% xfile.name %]
-- expect --
-- process --
name: [% file %]
# specify file via named parameter to constructor method
-- test --
[% USE xfile = XML( file = file ) -%]
name: [% xfile.name %]
-- expect --
-- process --
name: [% file %]
# specify file and dir via named params to constructor method
-- test --
[% USE xfile = XML( dir=dir, file=file ) -%]
name: [% xfile.name %]
dir: [% xfile.dir %]
-- expect --
-- process --
name: [% file %]
dir: [% dir %]
-- stop --
# TODO: more tests...
-- test --
[% XML.dom(file) %] and [% XML.dom(file=file) %]
-- test --
[% xdir.dom(file) %] and [% xdir.dom(file=file) %]
-- test --
[% xfile.dom %] => T::P::XML::DOM
# repeat above tests for xpath, simple and rss
# these tests below are copied from dom.t for reference
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(filename => xmlfile) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% global.xmltext = BLOCK %]
Hello World!
[% END -%]
[% USE dom = XML.DOM -%]
[% doc = dom.parse(global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(text => global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE dom = XML.DOM -%]
[% doc = dom.parse(xml => global.xmltext) -%]
[% FOREACH tag = doc.getElementsByTagName('page') -%]
* [% tag.href %] [% tag.title %]
[% END %]
-- expect --
* /foo/bar The Foo Page
* /bar/baz The Bar Page
* /baz/qux The Baz Page
-- test --
[% USE parser = XML.DOM -%]
[% doc = parser.parse(global.xmltext) -%]
[% FOREACH node = doc.getElementsByTagName('section') -%]
[% node.toTemplate %]
[% END %]
[% BLOCK section -%]
Section name: [% node.name %] title: [% node.title %]
[% node.childrenToTemplate -%]
[% END %]
[% BLOCK page -%]
[% node.title %]
[% node.childrenToTemplate -%]
[% END %]
[% BLOCK msg -%]
[% node.childrenToTemplate(verbose=1) %]
[% END %]
-- expect --
Section name: alpha title: The Alpha Zone
The Foo PageHello World!The Bar PageThe Baz Page
-- test --
[% xmltext = BLOCK %]
>
Andy Wardley
This is the first page
This is the second page
This is the first page in section b
This is the second page in section b
[% END -%]
[% USE parser = XML.DOM -%]
[% doc = parser.parse(xmltext) -%]
[% node.allChildrenToTemplate(default='anynode')
FOREACH node = doc.getChildNodes %]
[% BLOCK section -%]
SECTION [% node.id %]: [% node.title %]
[% children -%]
END OF SECTION [% node.id %]
[% END %]
[% BLOCK page -%]
PAGE: [% node.title %]
[% node.children -%]
END OF PAGE
[% END %]
[% BLOCK head -%]
HEADER: [% node.toString; prune %]END_HEADER
[% END %]
[% BLOCK anynode -%]
[% node.toString; node.prune %]
[% END %]
-- expect --
SECTION a: First Section
PAGE: page 1
HEADER: Andy WardleyEND_HEADER
This is the first page
END OF PAGE
PAGE: page 2
END OF PAGE
END OF SECTION a
SECTION b: Second Section
PAGE: page 1
END OF PAGE
PAGE: page 2
END OF PAGE
END OF SECTION b
Template-XML-2.17/t/xmlsimple.t 0000644 0001750 0001750 00000003724 10563113666 015677 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/xmlsimple.t
#
# Test the XML::Simple plugin.
#
# Written by Kenny Gatdula
#
# Copyright (C) 2004 Kenny Gatdula. All Rights Reserved.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: xmlsimple.t,v 1.2 2004/10/04 10:03:52 abw Exp $
#
#========================================================================
use strict;
use lib qw( ./lib ../lib );
use Template::Test;
use Cwd qw( abs_path );
$^W = 1;
$Template::Test::DEBUG = 0;
#$Template::Test::DEBUG = 1;
#$Template::Parser::DEBUG = 1;
#$Template::Directive::PRETTY = 1;
my $tt1 = Template->new({
INCLUDE_PATH => [ qw( t/test/lib test/lib ) ],
ABSOLUTE => 1,
});
ok(1);
eval "use XML::Simple";
if ($@ || $XML::Simple::VERSION < 2) {
skip_all('XML::Simple v2.0 or later not installed');
}
# account for script being run in distribution root or 't' directory
my $file = abs_path( -d 't' ? 't/test/xml' : 'test/xml' );
$file .= '/testfile.xml';
test_expect(\*DATA, $tt1, { 'xmlfile' => $file });
__END__
-- test --
[% TRY;
USE xmlsimple = XML.Simple('no_such_file');
CATCH;
error;
END
%]
-- expect --
file error - no_such_file: not found
-- test --
[% USE xml = XML.Simple(xmlfile) -%]
[% xml.section.name -%]
-- expect --
alpha
-- test --
[% USE xs = XML.Simple -%]
[% xml = xs.XMLin(xmlfile) -%]
[% xml.section.title -%]
-- expect --
The Alpha Zone
-- test --
[% USE XML;
xs = XML.simple
-%]
[% xml = xs.XMLin(xmlfile) -%]
[% xml.section.title -%]
-- expect --
The Alpha Zone
-- test --
[% USE xs = XML.Simple -%]
[% xml = xs.XMLin(xmlfile) -%]
[% xmlout = xs.XMLout(xml) -%]
[% xmlout -%]
-- expect --
Template-XML-2.17/t/xmlstyle.t 0000644 0001750 0001750 00000012164 10563113666 015544 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/xmlstyle.t
#
# Test the XML::Style plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2001 Canon Research Centre Europe Ltd.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: xmlstyle.t,v 1.5 2003/03/17 22:34:14 abw Exp $
#
#========================================================================
use strict;
use lib qw( ./lib ../lib ../blib/arch );
use Template;
use Template::Test;
use Cwd qw( abs_path );
$^W = 1;
$Template::Test::PRESERVE = 1;
test_expect(\*DATA);
__END__
-- test --
[% USE xmlstyle -%]
[% FILTER xmlstyle -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle foo = { element = 'bar' } -%]
[% FILTER xmlstyle -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle foo = { element = 'baz' } -%]
[% FILTER xmlstyle -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle -%]
[% FILTER xmlstyle foo = { element = 'wiz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle foo = { element = 'bar' } -%]
[% FILTER xmlstyle foo = { element = 'baz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle foo = { element = 'oof' } -%]
[% FILTER xmlstyle bar = { element = 'rab' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle -%]
[% FILTER xmlstyle foo = { attributes = { wiz = 'waz' } } -%]
The foo
[%- END %]
-- expect --
The foo
-- test --
[% USE xmlstyle foo = { attributes = { wiz = 'waz' } }-%]
[% FILTER xmlstyle bar = { attributes = { biz = 'boz' } } -%]
The foo blam
[%- END %]
-- expect --
The foo blam
-- test --
[% USE xmlstyle
list = {
element = 'ul'
pre_start = "
"
attributes = { class = 'mylist' }
}
item = {
element = 'li'
post_start = ''
pre_end = ''
post_end = "\n "
attributes = { class = 'myitem' }
}
-%]
[% FILTER xmlstyle -%]
The First ItemThe Second ItemThe Third Item
[%- END %]
-- expect --
The First Item
The Second Item
The Third Item
#------------------------------------------------------------------------
# test use of plugin filter via variable
#------------------------------------------------------------------------
-- test --
[% USE xmlstyle foo = { element = 'bar' } -%]
[% FILTER $xmlstyle -%]
The foo
[%- END %]
-- expect --
The foo
-- test --
[% USE xmlstyle foo = { element = 'bar' } -%]
[% FILTER $xmlstyle bar = { element = 'baz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE zap = xmlstyle foo = { element = 'bar' } -%]
[% FILTER $zap bar = { element = 'baz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE zap = xmlstyle foo = { element = 'bar' } -%]
[% FILTER $zap 'blaml' bar = { element = 'baz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
-- test --
[% USE xmlstyle 'zap' -%]
[% FILTER zap bar = { element = 'baz' } -%]
The fooThe bar
[%- END %]
-- expect --
The fooThe bar
#------------------------------------------------------------------------
# an example based on one from Tony Bowden posted to the mailing list
#------------------------------------------------------------------------
-- test --
[% USE xmlstyle
video = {
element = 'table'
attributes = { class='videoTable' },
}
title = {
pre_start = "
Template-XML-2.17/t/file.t 0000644 0001750 0001750 00000010172 10563113666 014577 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/file.t
#
# Test the XML::File plugin.
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2006 Andy Wardley. All Rights Reserved.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: dom.t,v 2.8 2002/08/12 11:07:14 abw Exp $
#
#========================================================================
use strict;
use warnings;
use lib qw( ./lib ../lib );
use Template;
use Template::Test;
use Cwd qw( abs_path );
local *FP;
my $dir = abs_path( -d 't' ? 't/xml' : 'xml' );
my $file = 'example.xml';
my $path = File::Spec->catfile($dir, $file);
open(FP, $path) || die "cannot open $path: $!";
my $vars = {
dir => $dir,
file => $file,
path => $path,
debug_on => sub { $Template::Plugin::XML::File::DEBUG = 1 },
debug_off => sub { $Template::Plugin::XML::File::DEBUG = 0 },
handle => \*FP,
};
test_expect(\*DATA, undef, $vars);
close(FP);
__END__
#------------------------------------------------------------------------
# test the $DEBUG package variable sets debugging on/off by default
# unless overridden by a debug named parameter
#------------------------------------------------------------------------
-- test --
[% CALL debug_on;
USE xf = XML.File('foo');
'debugging is '; xf.debug ? 'on' : 'off'
-%]
-- expect --
debugging is on
-- test --
[% CALL debug_off;
USE xf = XML.File('foo');
'debugging is '; xf.debug ? 'on' : 'off'
-%]
-- expect --
debugging is off
-- test --
[% USE xf = XML.File('foo', debug=1);
'debugging is '; xf.debug ? 'on' : 'off'
%]
-- expect --
debugging is on
-- test --
[% CALL debug_on;
USE xf=XML('foo', debug=0);
'debugging is '; xf.debug ? 'on' : 'off'
%]
-- expect --
debugging is off
#------------------------------------------------------------------------
# test the use of the positional argument to specify file name or handle
#------------------------------------------------------------------------
-- test --
[% USE xf = XML.File(file) -%]
type: [% xf.type or 'no type' %]
name: [% xf.name or 'no name' %]
handle: [% xf.handle or 'no handle' %]
-- expect --
-- process --
type: name
name: [% file %]
handle: no handle
-- test --
[% USE xf = XML.File(handle) -%]
type: [% xf.type or 'no type' %]
name: [% xf.name or 'no name' %]
handle: [% xf.handle or 'no handle' %]
-- expect --
-- process --
type: handle
name: no name
handle: [% handle %]
#------------------------------------------------------------------------
# test the use of named parameters for file name
#------------------------------------------------------------------------
-- test --
[% USE xf = XML.File(file=file) -%]
[% xf.type %]: [% xf.name %]
-- expect --
-- process --
name: [% file %]
-- test --
[% USE xf = XML.File(name=file) -%]
[% xf.type %]: [% xf.name %]
-- expect --
-- process --
name: [% file %]
-- test --
[% USE xf = XML.File(xml_file=file) -%]
[% xf.type %]: [% xf.name %]
-- expect --
-- process --
name: [% file %]
#------------------------------------------------------------------------
# test the use of named parameters for file handle
#------------------------------------------------------------------------
-- test --
[% USE xf = XML.File(fh=handle) -%]
[% xf.type %]: [% xf.handle %]
-- expect --
-- process --
handle: [% handle %]
-- test --
[% USE xf = XML.File(handle=handle) -%]
[% xf.type %]: [% xf.handle %]
-- expect --
-- process --
handle: [% handle %]
-- test --
[% USE xf = XML.File(xml_fh=handle) -%]
[% xf.type %]: [% xf.handle %]
-- expect --
-- process --
handle: [% handle %]
#------------------------------------------------------------------------
# test file() method
#------------------------------------------------------------------------
-- test --
[% USE XML;
file = XML.file(file)
-%]
file: [% file.name %]
-- expect --
-- process --
file: [% file %]
#------------------------------------------------------------------------
# TODO: dom(), xpath() and other methods.
#------------------------------------------------------------------------
Template-XML-2.17/t/domview.t 0000644 0001750 0001750 00000003733 10563113666 015337 0 ustar abw abw 0000000 0000000 #============================================================= -*-perl-*-
#
# t/domview.t
#
# Test the XML::DOM plugin presenting via a VIEW
#
# Written by Andy Wardley
#
# Copyright (C) 1996-2001 Andy Wardley. All Rights Reserved.
# Copyright (C) 1998-2001 Canon Research Centre Europe Ltd.
#
# This is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.
#
# $Id: domview.t,v 2.3 2002/08/12 11:07:14 abw Exp $
#
#========================================================================
use strict;
use lib qw( ./lib ../lib );
use Template;
use Template::Test;
use Cwd qw( abs_path );
$^W = 1;
#$Template::Test::DEBUG = 1;
#$Template::Test::PRESERVE = 1;
# I hate having to do this
my $shut_up_warnings = $XML::DOM::VERSION;
eval "use XML::DOM";
if ($@ || $XML::DOM::VERSION < 1.27) {
skip_all("XML::DOM v1.27 or later not installed");
}
test_expect(\*DATA);
__END__
-- test --
[% xmltext = BLOCK -%]
Blah blah.
Item 1
item 2
...
[% END -%]
[% USE dom = XML.DOM;
doc = dom.parse(text => xmltext);
report = doc.getElementsByTagName('report')
-%]
[% VIEW report_view notfound='xmlstring' %]
# handler block for a ... element
[% BLOCK report; item.content(view); END %]
# handler block for a ... element
[% BLOCK section -%]
[% item.title %]
[% 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 -%]
REPORT: [% report_view.print(report) | trim %]
-- expect --
REPORT:
Introduction
Blah blah.
Item 1
item 2
The Gory Details
...
Template-XML-2.17/lib/ 0000755 0001750 0001750 00000000000 10563116312 013764 5 ustar abw abw 0000000 0000000 Template-XML-2.17/lib/Template/ 0000755 0001750 0001750 00000000000 10563116312 015537 5 ustar abw abw 0000000 0000000 Template-XML-2.17/lib/Template/Plugin/ 0000755 0001750 0001750 00000000000 10563116312 016775 5 ustar abw abw 0000000 0000000 Template-XML-2.17/lib/Template/Plugin/XML/ 0000755 0001750 0001750 00000000000 10563116312 017435 5 ustar abw abw 0000000 0000000 Template-XML-2.17/lib/Template/Plugin/XML/DOM.pm 0000644 0001750 0001750 00000031372 10563113667 020432 0 ustar abw abw 0000000 0000000 #============================================================= -*-Perl-*-
#
# Template::Plugin::XML::DOM
#
# DESCRIPTION
# Simple Template Toolkit plugin interfacing to the XML::DOM.pm module.
#
# AUTHORS
# Andy Wardley
# Simon Matthews
#
# COPYRIGHT
# Copyright (C) 2000-2006 Andy Wardley, Simon Matthews.
#
# This module is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
#============================================================================
package Template::Plugin::XML::DOM;
use strict;
use warnings;
use base 'Template::Plugin';
use Template::Plugin::XML;
use XML::DOM;
our $VERSION = 2.70;
our $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");
bless {
PARSER => $parser,
DOCS => [ ],
CONTEXT => $context,
}, $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 ),
};
push(@{ $self->{ _DOCS } }, $doc);
return $doc;
}
#------------------------------------------------------------------------
# throw($errmsg)
#
# Raised a Template::Exception of type XML.DOM via die().
#------------------------------------------------------------------------
sub throw {
my $self = shift;
die $Template::Plugin::XML::EXCEPTION->new( 'XML.DOM' => join('', @_) );
}
#------------------------------------------------------------------------
# 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 } }) {
if (ref $doc) {
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);
}
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__
=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 = '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 [% node.title %]
[% END %]
# define VIEW to present node(s)
[% VIEW report notfound='xmlstring' %]
# handler block for a ... element
[% BLOCK report %]
[% item.content(view) %]
[% END %]
# handler block for a ... element
[% BLOCK section %]
[% item.title %]
[% item.content(view) %]
[% END %]
# default template block converts item to string
[% 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 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') %]
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!
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
character.
[% xmlfile = '/tmp/foo.xml' %]
[% doc = dom.parse(xmlfile) %]
[% xmltext = BLOCK %]
...
[% 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 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') %]
=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:
Blah blah.
Item 1
item 2
...
We can load it up via the XML::DOM plugin and fetch the node for the
EreportE 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 documentation
contains further details on the VIEW directive and various configuration
options it supports.
[% VIEW report_view notfound='xmlstring' %]
# handler block for a ... element
[% BLOCK report %]
[% item.content(view) %]
[% END %]
# handler block for a ... element
[% BLOCK section %]
[% item.title %]
[% 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:
Introduction
Blah blah.
Item 1
item 2
The Gory Details
...
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 and Simon Matthews.
The XML::DOM module is by Enno Derksen and Clark Cooper. It extends
the the XML::Parser module, also by Clark Cooper which itself is built
on James Clark's expat library.
=head1 COPYRIGHT
Copyright (C) 2000-2006 Andy Wardley, Simon Matthews.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=head1 SEE ALSO
L, L, L
Template-XML-2.17/lib/Template/Plugin/XML/View.pm 0000644 0001750 0001750 00000021012 10563113667 020713 0 ustar abw abw 0000000 0000000 #============================================================= -*-Perl-*-
#
# Template::Plugin::XML::View
#
# DESCRIPTION
# Template Toolkit plugin to parse XML and generate a view by raising
# events to a Template::View object for each element in the XML source.
#
# -- UNDER CONSTRUCTION -- NOT INCLUDED IN THE MAIN DISTRIBUTION --
#
# AUTHOR
# Andy Wardley
#
# COPYRIGHT
# Copyright (C) 2001-2004 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: View.pm,v 2.4 2003/03/17 22:29:16 abw Exp $
#
#============================================================================
package Template::Plugin::XML::View;
require 5.004;
use strict;
use Template::Plugin;
use XML::Parser;
use base qw( Template::Plugin );
use vars qw( $VERSION $DEBUG $XML_PARSER_ARGS $ELEMENT );
$VERSION = sprintf("%d.%02d", q$Revision: 2.4 $ =~ /(\d+)\.(\d+)/);
$DEBUG = 0 unless defined $DEBUG;
$XML_PARSER_ARGS = {
ErrorContext => 4,
Namespaces => 1,
ParseParamEnt => 1,
NoExpand => 1,
};
$ELEMENT = 'Template::Plugin::XML::View::Element';
#------------------------------------------------------------------------
# new($context, $file_or_text, \%config)
#------------------------------------------------------------------------
sub new {
my $class = shift;
my $context = shift;
my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { };
my ($input, $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 ($input = shift) {
if ($input =~ /\) {
$about = 'xml text';
}
else {
$about = "xml file $input";
$input = $class->file_contents($input);
}
}
elsif ($input = $args->{ text } || $args->{ xml }) {
$about = 'xml text';
}
elsif ($input = $args->{ file } || $args->{ filename }) {
$about = "xml file $input";
$input = $class->file_contents($input);
}
else {
$class->throw('no filename or xml text specified');
}
# munge input to protect entity refs
$input =~ s/&/&/g;
my $xpargs = {
map { exists $args->{$_}
? ( $_, $args->{ $_ } )
: ( $_, $XML_PARSER_ARGS->{ $_ } ) }
keys %$XML_PARSER_ARGS,
};
my $parser = XML::Parser->new(
%$xpargs,
Style => 'Template::Plugin::XML::View::Parser',
Handlers => {
Init => sub {
my $expat = shift;
DEBUG("[Init]\n") if $DEBUG;
$expat->{ _TT2_XVIEW_TEXT } = '';
$expat->{ _TT2_XVIEW_RESULT } = '';
$expat->{ _TT2_XVIEW_CONTEXT } = $context;
$expat->{ _TT2_XVIEW_STACK } = [ ];
},
},
);
my $result = $parser->parse($input);
DEBUG("result: $result\n") if $DEBUG;
return $result;
}
sub file_contents {
my ($self, $file) = @_;
my $text;
local *FP;
local $/ = undef;
open(FP, $file) || $self->throw("cannot read XML file $file: $!");
$text = ;
close(FP);
return $text;
}
#------------------------------------------------------------------------
# _throw($errmsg)
#
# Raise a Template::Exception of type XML.View via die().
#------------------------------------------------------------------------
sub throw {
my ($self, $error) = @_;
die (Template::Exception->new('XML.View', $error));
}
sub DEBUG { print STDERR @_ };
#========================================================================
# Template::Plugin::XML::View::Parser
#
# Package defines subroutines which are called by the XML::Parser
# instance. They manipulate a stack of T-::P-::XML::View::Element
# objects which each represent nested elements currently under parse
# at any time, with the innermost element object on top of the stack.
# These subs call the element()
#========================================================================
package Template::Plugin::XML::View::Parser;
use vars qw( $DEBUG $ELEMENT );
*DEBUG = \*Template::Plugin::XML::View::DEBUG;
$ELEMENT = 'Template::Plugin::XML::View::Element';
sub Start {
my ($expat, $name, %attr) = @_;
my $attr = \%attr;
# flush any character content
Text($expat) if length $expat->{ _TT2_XVIEW_TEXT };
if ($DEBUG) {
my $iattr = join(' ', map { "$_=\"$attr{$_}\"" } keys %attr);
$attr = " $attr" if $attr;
DEBUG("[Start] <$name$attr>\n");
}
my $stack = $expat->{ _TT2_XVIEW_STACK };
my $element = $ELEMENT->new($name, \%attr)
|| $stack->[-1]->throw($ELEMENT->error());
push(@$stack, $element);
}
sub End {
my ($expat, $name) = @_;
# flush any character content
Text($expat) if length $expat->{ _TT2_XVIEW_TEXT };
DEBUG("[End] $name>\n") if $DEBUG;
my $stack = $expat->{ _TT2_XVIEW_STACK };
my $top = pop(@$stack);
my $end = $top->end($expat, $name)
|| $top->throw($top->error());
if (@$stack) {
$stack->[-1]->child($expat, $name, $end);
}
else {
DEBUG("popped last handler off stack\n") if $DEBUG;
# die "corrupt stack\n";
$expat->{ _TT2_XVIEW_RESULT } = $end;
}
}
sub Char {
my ($expat, $char) = @_;
DEBUG("[Char] [$char]\n") if $DEBUG;
# push character content onto buffer
$expat->{ _TT2_XVIEW_TEXT } .= $char;
}
#------------------------------------------------------------------------
# Text()
#
# This is an extension subroutine which we're using to buffer chunks
# of Char input into complete text blocks. These then get notified to
# the parent in one happy bundle rather than several scraggly lumps.
#------------------------------------------------------------------------
sub Text {
my $expat = shift;
my $text = $expat->{ _TT2_XVIEW_TEXT };
if ($DEBUG) {
my $dbgtext = $text;
$dbgtext =~ s/\n/\\n/g;
DEBUG("[Text] [$dbgtext]\n") if $DEBUG;
}
$expat->{ _TT2_XVIEW_STACK }->[-1]->text($expat, $text);
$expat->{ _TT2_XVIEW_TEXT } = '';
}
sub Final {
my $expat = shift;
return $expat->{ _TT2_XVIEW_RESULT } || die "no result\n";
my $stack = $expat->{ _TT2_XVIEW_STACK };
my $top = pop(@$stack) || die "corrupt stack in Final";
my $end = $top->end($expat)
|| $top->throw($top->error());
my $r = $expat->{ _TT2_XVIEW_RESULT } || die "no result\n";# $end;
DEBUG("[Final] => [$r]\n") if $DEBUG;
return $r;
}
#========================================================================
# Template::Plugin::XML::View::Element
#
# Implements a parser handler for representing each element in the
#========================================================================
package Template::Plugin::XML::View::Element;
sub new {
my ($class, $name, $attr) = @_;
bless {
name => $name,
attr => $attr,
content => [ ],
}, $class;
}
# called to receive character content
sub text {
my $self = shift;
my $expat = shift;
push(@{ $self->{ content } }, @_);
}
# called to receive completed child element
sub child {
my ($self, $expat, $name, $child) = @_;
push(@{ $self->{ content } }, $child);
}
# called at end of element
sub end {
my ($self, $expat, $name) = @_;
return $self;
}
# generate element as XML
sub xml {
my $self = shift;
my $name = $self->{ name };
# generate XML representation of attributes
my $attr = $self->{ attr };
$attr = join(' ', map {
"$_=\"$attr->{$_}\"";
} keys %$attr);
$attr = " $attr" if length $attr;
# generate XML representation of content
my $content = $self->{ content };
$content = join(' ', map {
ref $_ ? $_->xml() : $_;
} @$content);
# generate complete XML element
return length $content
? "<${name}${attr}>$content$name>"
: "<${name}${attr} />";
}
sub present {
my ($self, $view) = @_;
my $vars = {
%$self,
%{ $self->{ attr } },
element => $self,
content => sub { $self->content($view) },
};
$view->include($self->{ name }, $vars)
}
sub content {
my ($self, $view) = @_;
return $self->{ content } unless $view;
my $output = '';
foreach my $node (@{ $self->{ content } }) {
$output .= ref $node ? $node->present($view) : $node;
}
return $output;
}
1;
__END__
Template-XML-2.17/lib/Template/Plugin/XML/XPath.pm 0000644 0001750 0001750 00000015664 10563114017 021033 0 ustar abw abw 0000000 0000000 #============================================================= -*-Perl-*-
#
# Template::Plugin::XML::XPath
#
# DESCRIPTION
# Template Toolkit plugin interfacing to the XML::XPath.pm module.
#
# AUTHOR
# Andy Wardley
#
# COPYRIGHT
# Copyright (C) 2000-2006 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.
#
#============================================================================
package Template::Plugin::XML::XPath;
use strict;
use warnings;
use Template::Exception;
use base 'Template::Plugin';
use XML::XPath;
our $VERSION = 2.71;
#------------------------------------------------------------------------
# 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) = @_;
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. &
#----------------------------------------------------------------------
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__
=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 ... element
[% BLOCK report %]
[% item.content(view) %]
[% END %]
# handler block for a ... element
[% BLOCK section %]
[% item.getAttribute('title') | html %]
[% 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 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.
The XML::XPath module is by Matt Sergeant.
=head1 COPYRIGHT
Copyright (C) 1996-2006 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.
=head1 SEE ALSO
L, L, L
Template-XML-2.17/lib/Template/Plugin/XML/RSS.pm 0000644 0001750 0001750 00000010063 10563113667 020454 0 ustar abw abw 0000000 0000000 #============================================================= -*-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
#
# COPYRIGHT
# Copyright (C) 2000-2006 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.
#
#============================================================================
package Template::Plugin::XML::RSS;
use strict;
use warnings;
use base 'Template::Plugin';
use XML::RSS;
our $VERSION = 2.66;
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__
=head1 NAME
Template::Plugin::XML::RSS - Plugin interface to XML::RSS
=head1 SYNOPSIS
[% USE news = XML.RSS('news.rdf') %]
[% FOREACH item IN news.items %]
[% item.title %]
[% item.link %]
[% END %]
=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.
Slashdot:News for Nerds. Stuff that Matters.
http://slashdot.org
News for Nerds. Stuff that MattersSlashdothttp://slashdot.org/images/slashdotlg.gif
http://slashdot.org
DVD CCA Battle Continues Next Week
http://slashdot.org/article.pl?sid=00/01/12/2051208
Matrox to fund DRI Development
http://slashdot.org/article.pl?sid=00/01/13/0718219
Mike Shaver Leaving Netscape
http://slashdot.org/article.pl?sid=00/01/13/0711258
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 IN news.items %]
[% item.title %]
[% item.link %]
[% END %]
=head1 AUTHORS
This plugin was written by Andy Wardley inspired by an article in Web
Techniques by Randal Schwartz.
The XML::RSS module, which implements all of the functionality that
this plugin delegates to, was written by Jonathan Eisenzopf.
=head1 COPYRIGHT
Copyright (C) 1996-2006 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.
=head1 SEE ALSO
L, L, L
Template-XML-2.17/lib/Template/Plugin/XML/LibXML.pm 0000644 0001750 0001750 00000046535 10563113667 021111 0 ustar abw abw 0000000 0000000 #============================================================= -*-Perl-*-
#
# Template::Plugin::XML::LibXML
#
# DESCRIPTION
# Template Toolkit plugin interfacing to the XML::LibXML.pm module.
#
# AUTHORS
# Mark Fowler
# Andy Wardley
#
# COPYRIGHT
# Copyright (C) 2002-3 Mark Fowler, 2006 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.
#
#============================================================================
package Template::Plugin::XML::LibXML;
require 5.004;
use strict;
use warnings;
use base 'Template::Plugin';
use Template::Plugin::XML;
use XML::LibXML;
# load the recommended (but not manditory) openhandle routine
# for filehandle detection.
BEGIN { eval "use Scalar::Util qw(openhandle)" }
our $VERSION = 2.00;
# these are a list of combatibilty mappings from names that were used
# (or logical extensions of those names for html) in the XML::XPath
# plugin. Though we're using existing names, I want you to be able
# to still use the old names. Very DWIM
use constant TYPE => {
'xml' => 'string',
'text' => 'string',
'filename' => 'file',
'html' => 'html_string',
'html_text' => 'html_string',
'html_file' => 'html_file',
'html_filename' => 'html_file',
};
#------------------------------------------------------------------------
# new($context, \%config)
#
# Constructor method for XML::LibXML plugin. Creates an XML::LibXML
# object and initialises plugin configuration.
#------------------------------------------------------------------------
sub new {
my $class = shift;
my $context = shift;
my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { };
my $type; # how we're going to get out data
my $content; # a ref to the data
local $_;
# work out what data we should process
if (@_) {
# ah, we got positional data.
$content = \$_[0]; # remember where it is
$type = _guess_type($_[0]); # guess what type we're doing
}
else {
# okay, the data must be in the named parameters
# first up we'll just try the method names. You really should
# supply the arguments like this you know.
foreach (qw(string file fh html_string html_file html_fh)) {
if ($args->{ $_ }) {
$content = \$args->{ $_ }; # remember where it is
delete $args->{ $_ }; # don't pass on parameter though
$type = $_; # remember what type we're doing
last; # skip to the end
}
}
unless ($type) {
# last ditch effort. In this case we'll try some of the names
# that the XML::XPath plugin uses. We might strike lucky
foreach (keys %{ &TYPE }) {
if ($args->{ $_ }) {
$content = \$args->{ $_ }; # remember where it is
delete $args->{ $_ }; # don't pass on parameter though
$type = &TYPE->{ $_ }; # remember what type we're doing
last; # skip to the end
}
}
}
}
# return an error if we didn't get a response back
return $class->_throw('no filename, handle or text specified')
unless $type;
# create a parser
my $parser = XML::LibXML->new();
# set the options
foreach my $method (keys %$args) {
# try setting the method
eval { $parser->$method($args->{$method}) };
# if there's a problem throw a Tempalte::Exception
$self->throw("option '$method' not supported") if $@;
}
# parse
my $method = "parse_$type";
return $parser->$method($$content);
}
#------------------------------------------------------------------------
# _guess_type($string)
#
# Guesses what type of data this is
#------------------------------------------------------------------------
sub _guess_type
{
# look for a filehandle
return "fh" if _openhandle($_[0]);
# okay, look for the xml declaration at the start
return "string" if $_[0] =~ m/^\<\?xml/;
# okay, look for the html declaration anywhere in the doc
return "html_string" if $_[0] =~ m//i;
# okay, does this contain a "<" symbol, and declare it to be
# xml if it's got one, though they should use "new( 'XML.LibXML' => join('', @_) );
}
#------------------------------------------------------------------------
# _openhandle($scalar)
#
# Determines if this is probably an open filehandle or not.
#
# uses openhandle from Scalar::Util if we have it.
#------------------------------------------------------------------------
sub _openhandle ($)
{
return openhandle($_[0]) if defined(&openhandle);
# poor man's openhandle
return defined(fileno $_[0]);
}
#========================================================================
package XML::LibXML::Node;
#========================================================================
#-----------------------------------------------------------------------
# present($view)
#
# Method to present an node via a view, using the block that has the
# same localname.
#-----------------------------------------------------------------------
# note, should this worry about namespaces? Probably. Hmm.
sub present {
my ($self, $view) = @_;
my $localname = $self->localname();
# convert anything that isn't A-Za-z1-9 to _. All those years
# of working on i18n and this throws it all away. I suck.
$localname =~ s/[^A-Za-z0-9]/_/g;
# render out with the block matching the hacked version of localname
$view->view($localname, $self);
}
#-----------------------------------------------------------------------
# content($view)
#
# Method present the node's children via a view
#-----------------------------------------------------------------------
sub content {
my ($self, $view) = @_;
my $output = '';
foreach my $node ($self->childNodes ) {
$output .= $node->present($view);
}
return $output;
}
#----------------------------------------------------------------------
# starttag(), endtag()
#
# Methods to output the start & end tag, e.g.
# and
#----------------------------------------------------------------------
sub starttag {
my ($self) = @_;
my $output = "<". $self->nodeName();
foreach my $attr ($self->attributes)
{
$output .= $attr->toString();
}
$output .= ">";
return $output;
}
sub endtag {
my ($self) = @_;
return "". $self->nodeName() . ">";
}
#========================================================================
package XML::LibXML::Document;
#========================================================================
#------------------------------------------------------------------------
# present($view)
#
# Method to present a document node via a view.
#------------------------------------------------------------------------
sub present {
my ($self, $view) = @_;
# okay, just start rendering from the first element, ignore the pi
# and all that
$self->documentElement->present($view);
}
#========================================================================
package XML::LibXML::Text;
#========================================================================
#------------------------------------------------------------------------
# present($view)
#
# Method to present a text node via a view.
#------------------------------------------------------------------------
sub present {
my ($self, $view) = @_;
$view->view('text', $self->data); # same as $self->nodeData
}
#========================================================================
package XML::LibXML::NodeList;
#========================================================================
#------------------------------------------------------------------------
# present($view)
#
# Method to present a node list via a view. This is only normally useful
# when you call outside of TT as findnodes will be called in list context
# normally
#------------------------------------------------------------------------
sub present {
my ($self, $view) = @_;
my $output = '';
foreach my $node ($self->get_nodelist ) {
$output .= $node->present($view);
}
return $output;
}
#package debug;
#sub debug
#{
# local $^W;
# my $nodename;
# eval { $nodename = $_[0]->nodeName(); };
# my $methodname = (caller(1))[3];
# $methodname =~ s/.*:://;
#
# print STDERR "${nodename}'s $methodname: ".
# (join ",", (map { ref } @_)) .
# "\n";
#}
1;
__END__
=head1 NAME
Template::Plugin::XML::LibXML - XML::LibXML Template Toolkit Plugin
=head1 SYNOPSIS
[% USE docroot = XML.LibXML("helloworld.xml") %]
The message is: [% docroot.find("/greeting/text") %]
=head1 DESCRIPTION
This module provides a plugin for the XML::LibXML module. It can be
utilised the same as any other Template Toolkit plugin, by using a USE
statement from within a Template. The use statment will return a
reference to root node of the parsed document
=head2 Specifying a Data Source
The plugin is capable of using either a string, a filename or a
filehandle as a source for either XML data, or HTML data which will be
converted to XHTML internally.
The USE statement can take one or more arguments to specify what XML
should be processed. If only one argument is passed then the plugin
will attempt to guess how what it has been passed should be
interpreted.
When it is forced to guess what type of data it is used the routine
will first look for an open filehandle, which if it finds it will
assume it's a filehandle to a file containing XML. Failing this (in
decreasing order) it will look for the chars "" tag (and assume it's HTML string,) look for a "<" (and assume
it's XML string without a header,) or assume what it's been passed is
the filename to a file containing XML.
In the interests of being explicit, you may specify the type of
data you are loading using the same names as in the B
documentation:
# value contains the xml string
[% USE docroot = XML.LibXML(string => value) %]
# value contains the filename of the xml
[% USE docroot = XML.LibXML(file => value) %]
# value contains an open filehandle to some xml
[% USE docroot = XML.LibXML(fh => value) %]
# value contains the html string
[% USE docroot = XML.LibXML(html_string => value) %]
# value contains the filename of the html
[% USE docroot = XML.LibXML(html_file => value) %]
# value contains an open filehandle to some html
[% USE docroot = XML.LibXML(html_fh => value) %]
Or, if you want you can use similar names to that the XML.XPath
plugin uses:
# value contains the xml string
[% USE docroot = XML.LibXML(xml => value) %] or
[% USE docroot = XML.LibXML(text => value) %]
# value contains the filename of the xml
[% USE docroot = XML.LibXML(filename => value) %]
# value contains the html string
[% USE docroot = XML.LibXML(html => value) %] or
[% USE docroot = XML.LibXML(html_text => value) %]
# value contains the filename of the html
[% USE docroot = XML.LibXML(html_file => value) %]
[% USE docroot = XML.LibXML(html_filename => value) %]
You can provide extra arguments which will be used to set parser
options. See L for details on these. I will repeat the
following warning however: "LibXML options are global (unfortunately
this is a limitation of the underlying implementation, not this
interface)...Note that even two forked processes will share some of
the same options, so be careful out there!"
# turn off expanding entities
[% USE docroot = XML.LibXML("file.xml",
expand_entities => 0);
=head2 Obtaining Parts of an XML Document
XML::LibXML provides two simple mechanisms for obtaining sections
of the XML document, both of which can be used from within
the Template Toolkit
The first of these is to use a XPath statement. Simple values
can be found with the C routine:
# get the title attribute of the first page node
# (note xpath starts counting from one not zero)
[% docroot.findvalue("/website/section/page[1]/@title"); %]
# get the text contained within a node
[% htmldoc.findvalue("/html/body/h1[1]/text()") %]
Nodes of the xml document can be found with the C
# get all the pages ('pages' is a list of nodes)
[% pages = docroot.findnodes("/website/section/page") %]
# get the first page (as TT folds single elements arrays
# to scalars, 'page1' is the one node that matched)
[% page1 = docroot.findnodes("/website/section/page[1]") %]
Then further xpath commands can then be applied to those
nodes in turn:
# get the title attribute of the first page
[% page1.findvalue("@title") %]
An alternative approach is to use individual method calls to move
around the tree. So the above could be written:
# get the text of the h1 node
[% htmlroot.documentElement
.getElementsByLocalName("body").first
.getElementsByLocalName("h1").first
.textContent %]
# get the title of the first page
[% docroot.documentElement
.getElementsByLocalName("section").first
.getElementsByLocalName("page").first
.getAttribute("title") %]
You should use the technique that makes the most since in the
particular situation. These approaches can even be mixed:
# get the first page title
[% page1 = htmlroot.findnodes("/website/section/page[1]");
page1.getAttribute("title") %]
Much more information can be found in L.
=head2 Rendering XML
The simplest way to use this plugin is simply to extract each value
you want to print by hand
The title of the first page is '[%
docroot.findvalue("/website/section/page[1]/@title") %]'
or
The title of the first page is '[%
docroot.documentElement
.getElementsByLocalName("section").first
.getElementsByLocalName("page").first
.getAttribute("title") %]'
You might want to discard whitespace from text areas. XPath
can remove all leading and following whitespace, and condense
all multiple spaces in the text to single spaces.
[% htmlroot.findvalue("normalize-space(
/html/body/p[1]/text()
)" | html %]
Note that, as above, when we're inserting the values extracted into a
XML or HTML document we have to be careful to re-encode the attributes
we need to escape with something like the html filter. A slightly
more advanced technique is to extract a whole node and use the
toString method call on it to convert it to a string of XML. This is
most useful when you are extracting an existing chunk of XML en mass,
as things like EbE and EiE tags will be passed thought
correctly and entities will be encoded suitably (for example '"' will
be turned into '"')
# get the second paragraph and insert it here as XML
[% htmlroot.findnodes("/html/body/p[2]").toString %]
The most powerful technique is to use a view (as defined by the VIEW
keyword) to recursively render out the XML. By loading this plugin
C methods will be created in the B classes
and subclasses. Calling C on a node with a VIEW will cause
it to be rendered by the view block matching the local name of that
node (with any non alphanumeric charecters turned to underscores. So
a EauthorE tag will be rendered by the 'author' block. Text
nodes will call the 'text' block with the text of the node.
As the blocks can refer back to both the node it was called with and
the view they can choose to recursively render out it's children using
the view again. To better facilitate this technique the extra methods
C (recreate a string of the starting tag, including
attributes,) C (recreate a string of the ending tag) and
C (when called with a view, will render by calling all the
children of that node in turn with that view) have been added.
This is probably best shown with a well commented example:
# create the view
[% VIEW myview notfound => 'passthru' %]
# default tag that will recreate the tag 'as is' meaning
# that unknown tags will 'passed though' by the view
[% BLOCK passthru; item.starttag;
item.content(view);
item.endtag;
END %]
# convert all sections to headed paragraphs
[% BLOCK section %]
[% item.getAttribute("title") %]
[% item.content(view) %]
[% END %]
# urls link to themselves
[% BLOCK url %]
[% item.content(view) %]
[% END %]
# email link to themselves with mailtos
[% BLOCK email %]
[% item.content(view) %]
[% END %]
# make pod links bold
[% BLOCK pod %]
[% item.content(view) %]
[% END %]
# render text, re-encoding the attributes as we go
[% BLOCK text; item | html; END %]
# render arrays out
[% BLOCK list; FOREACH i = item; view.print(i); END ; END %]
[% END %]
# use it to render the paragraphs
[% USE doc = XML.LibXML("mydoc.xml") %]
[% doc.findvalue("/doc/page[1]/@title") %]
[% sections = doc.findnodes("/doc/page[1]/section");
FOREACH section = sections %]
[% section.present(myview);
END %]
=head1 BUGS
In order to detect if a scalar is an open filehandle (which is used if
the USE isn't explicit about it's data source) this plugin uses the
C routine from B. If you do not have
B installed, or the version of B is
sufficiently old that it does not support the C routine
then a much cruder C check will be employed.
Bugs may be reported either via the CPAN RT at
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Template-Plugin-XML-LibXML
or via the Template Toolkit mailing list:
http://www.template-toolkit.org/mailman/listinfo/templates or direct
to the author
=head1 AUTHOR
Written by Mark Fowler
Copyright Mark Fowler 2002-3, all rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
This module wouldn't have been possible without the wonderful work
that has been put into the libxml library by the gnome team or the
equally wonderful work put in by Matt Sergeant and Christian Glahn in
creating XML::LibXML.
=head1 SEE ALSO
L, L, L, L.
On a similar note, you may want to see L.
The t/test directory in the Template-Plugin-XML-LibXML distribution
contains all the example XML files discussed in this documentation.
=cut
Template-XML-2.17/lib/Template/Plugin/XML/Simple.pm 0000644 0001750 0001750 00000004723 10563113667 021244 0 ustar abw abw 0000000 0000000 #============================================================= -*-Perl-*-
#
# Template::Plugin::XML::Simple
#
# DESCRIPTION
# Template Toolkit plugin interfacing to the XML::Simple.pm module.
#
# AUTHOR
# Andy Wardley
#
# COPYRIGHT
# Copyright (C) 2001-2006 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.
#
#============================================================================
package Template::Plugin::XML::Simple;
use strict;
use warnings;
use base 'Template::Plugin';
use XML::Simple;
our $VERSION = 2.66;
#------------------------------------------------------------------------
# new($context, $file_or_text, \%config)
#------------------------------------------------------------------------
sub new {
my $class = shift;
my $context = shift;
my $input = shift;
my $args = ref $_[-1] eq 'HASH' ? pop(@_) : { };
if (defined($input)) {
# an input parameter can been be provided and can contain
# XML text or the filename of an XML file, which we load
# using insert() to honour the INCLUDE_PATH; then we feed
# it into XMLin().
$input = $context->insert($input) unless ( $input =~ / );
return XMLin($input, %$args);
}
else {
# otherwise return a XML::Simple object
return new XML::Simple;
}
}
#------------------------------------------------------------------------
# _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__
=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 AUTHORS
This plugin wrapper module was written by Andy Wardley.
The XML::Simple module which implements all the core functionality was
written by Grant McLean.
=head1 COPYRIGHT
Copyright (C) 1996-2006 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.
=head1 SEE ALSO
L, L, L
Template-XML-2.17/lib/Template/Plugin/XML/Style.pm 0000644 0001750 0001750 00000016117 10563113667 021113 0 ustar abw abw 0000000 0000000 #============================================================= -*-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
#
# COPYRIGHT
# Copyright (C) 2001-2006 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.
#
#============================================================================
package Template::Plugin::XML::Style;
use strict;
use warnings;
use base 'Template::Plugin::Filter';
our $VERSION = 2.36;
our $DYNAMIC = 1;
our $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__
=head1 NAME
Template::Plugin::XML::Style - Simple XML stylesheet transfomations
=head1 SYNOPSIS
[% USE xmlstyle
table = {
attributes = {
border = 0
cellpadding = 4
cellspacing = 1
}
}
%]
[% FILTER xmlstyle %]
Foo
Bar
Baz
[% 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 and
C can be added to EtableE elements.
[% USE xmlstyle
table = {
attributes = {
border = 0
cellpadding = 4
}
}
%]
[% FILTER xmlstyle %]
...
[% END %]
This produces the output:
...
Parameters specified within the USE directive are applied
automatically each time the C 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"
}
}
%]
...
[% 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 %]
foo
bar
[% END %]
The output produced is:
foo
bar
The filter can also be used to change the element from one type to
another.
[% FILTER xmlstyle
th = {
element = 'td'
attributes = { bgcolor='red' }
}
%]
Heading
Value
[% END %]
The output here is as follows. Notice how the end tag
C/thE> is changed to C/tdE> as well as the start
tag.
Heading
Value
You can also define text to be added immediately before or after the
start or end tags. For example:
[% FILTER xmlstyle
table = {
pre_start = '
=head1 AUTHOR
Andy Wardley
=head1 COPYRIGHT
Copyright (C) 2001-2006 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.
=head1 SEE ALSO
L
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:
Template-XML-2.17/lib/Template/Plugin/XML/File.pm 0000644 0001750 0001750 00000012061 10563113667 020664 0 ustar abw abw 0000000 0000000 package Template::Plugin::XML::File;
use strict;
use warnings;
use Template::Plugin::XML;
use base 'Template::Plugin::File';
our $VERSION = 2.15;
our $DEBUG = 0 unless defined $DEBUG;
our $EXCEPTION = 'Template::Exception' unless defined $EXCEPTION;
our $XML_PLUGIN = 'Template::Plugin::XML' unless defined $XML_PLUGIN;
our $FILE_TYPES = {
name => 'name',
file => 'name',
xml_file => 'name',
fh => 'handle',
handle => 'handle',
xml_fh => 'handle',
};
sub new {
my $class = shift;
my $context = shift;
my $params = @_ && ref $_[-1] eq 'HASH' ? pop(@_) : { };
my ($source, $type);
my $self = bless {
debug => delete $params->{ debug },
libxml => delete $params->{ libxml },
}, $class;
# apply default for debug from package variable
$self->{ debug } = $DEBUG unless defined $self->{ debug };
if (@_) {
# first positional argument is file name or XML string
$source = shift;
$type = $XML_PLUGIN->detect_filehandle($source) ? 'handle' : 'name';
$self->{ type } = $type;
$self->{ $type } = $source;
}
else {
# look in named params for a known type
while (my ($param, $type) = each %$FILE_TYPES) {
if (defined ($source = delete $params->{ $param })) {
$self->{ type } = $type;
$self->{ $type } = $source;
}
}
}
return $self->throw('a file name or file handle must be specified')
unless defined $self->{ type };
return $self;
}
sub type {
return $_[0]->{ type };
}
sub name {
return $_[0]->{ name };
}
sub libxml {
my $self = shift;
return $self->{ libxml };
}
sub dom {
my $self = shift;
my $args = @_ && ref $_[-1] eq 'HASH' ? pop(@_) : { };
return $self->{ dom } ||= do {
my ($parser, $dom);
if ($parser = $self->{ libxml }) {
if (defined $self->{ name }) {
# file name
eval { $dom = $parser->parse_file($self->{ name }) }
|| $self->throw("failed to parse $self->{ name }: $@");
}
else {
# file handle
eval { $dom = $parser->parse_fh($self->{ handle }) }
|| $self->throw("failed to parse file handle: $@");
}
}
else {
eval { require XML::DOM }
|| $self->throw("XML::DOM not available: $@");
$parser = XML::DOM::Parser->new(%$args)
|| $self->throw("failed to create parser");
# TODO: must call dispose() on any XML::DOM documents we create
if (defined $self->{ name }) {
# file name
eval { $dom = $parser->parsefile($self->{ name }) }
|| $self->throw("failed to parse $self->{ name }: $@");
}
else {
# file handle
local $/ = undef;
my $fh = $self->{ handle };
my $text = <$fh>;
eval { $dom = $parser->parse($text) }
|| $self->throw("failed to parse $self->{ name }: $@");
}
}
$dom;
};
}
#------------------------------------------------------------------------
# handle()
#
# TODO: this currently returns the handle iff one was specified as a
# constructor arg, and undef otherwise. But it would be nice if it
# opened the file for you (using any mode/write/append/create params
# specified either in the constructor or as args) and returned the handle.
# Then you could write [% dir.file('foo.xml').handle %]
#------------------------------------------------------------------------
sub handle {
return $_[0]->{ handle };
}
sub debug {
return $_[0]->{ debug };
}
sub throw {
my $self = shift;
die $Template::Plugin::XML::EXCEPTION->new( 'XML.File' => join('', @_) );
}
1;
__END__
=head1 NAME
Template::Plugin::XML::File - TT plugin for XML files
=head1 SYNOPSIS
# different want to specify an XML file name
[% USE xf = XML.File( filename ) %]
[% USE xf = XML.File( file = filename ) %]
[% USE xf = XML.File( name = filename ) %]
[% USE xf = XML.File( xml_file = filename ) %]
# different want to specify an XML file handle
[% USE xf = XML.File( handle ) %]
[% USE xf = XML.File( fh = handle ) %]
[% USE xf = XML.File( handle = handle ) %]
[% USE xf = XML.File( xml_fh = handle ) %]
[% xf.type %] # 'name' or 'handle'
[% xf.name %] # filename (if defined)
[% xf.handle %] # file handle (if defined)
=head1 DESCRIPTION
TODO
=head1 METHODS
TODO
=head1 AUTHORS
Andy Wardley, Mark Fowler and others...
=head1 COPYRIGHT
TODO
=head1 SEE ALSO
L, L,
L, L,
L, L
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:
Template-XML-2.17/lib/Template/Plugin/XML.pm 0000644 0001750 0001750 00000024016 10563114352 020000 0 ustar abw abw 0000000 0000000 package Template::Plugin::XML;
use strict;
use warnings;
use base 'Template::Plugin';
our $VERSION = 2.17;
our $DEBUG = 0 unless defined $DEBUG;
our $EXCEPTION = 'Template::Exception' unless defined $EXCEPTION;
our $LIBXML = eval { require XML::LibXML } unless defined $LIBXML;
our $OPENHANDLE = eval "use Scalar::Util qw(openhandle)";
our @TYPES = qw( file fh text
xml xml_file xml_fh xml_text
html html_file html_fh html_text );
sub new {
my $class = shift;
my $context = shift;
my $params = @_ && ref $_[-1] eq 'HASH' ? pop(@_) : { };
my ($source, $type);
if (@_) {
# first positional argument is file name or XML string
$source = shift;
$type = $class->detect_type($source);
}
else {
# look in named params for a known type
foreach (@TYPES) {
$type = $_, last
if defined ($source = delete $params->{ $_ });
}
}
my $self = bless {
context => $context,
debug => delete $params->{ debug },
libxml => delete $params->{ libxml },
}, $class;
# apply defaults for debug and libxml from package variable
$self->{ debug } = $DEBUG unless defined $self->{ debug };
$self->{ libxml } = $LIBXML unless defined $self->{ libxml };
# if libxml is enabled then we create an XML::LibXML parser
$self->{ libxml } &&= do {
# make sure they didn't try and force libxml=>1 when $LIBXML
# says we haven't got XML::LibXML installed
return $self->throw('XML::LibXML is not available')
unless $LIBXML;
my $parser = XML::LibXML->new();
# iterate through remaining params trying to call the
# appropriate method on the XML::LibXML object, e.g.
# expand_entities => 1 becomes $parse->expand_entities(1)
my ($param, $value, $method);
while (($param, $value) = each %$params) {
# throw an error if the parser doesn't have the method
$self->throw("invalid configuration parameter: $param")
unless ($method = UNIVERSAL::can($parser, $param));
# catch any errors thrown and re-throw as our exceptions
eval { &$method($parser, $value) };
$self->throw("configuration parameter '$param' failed: $@")
if $@;
}
$parser;
};
return $self;
}
sub source {
return $_[0]->{ source };
}
sub type {
return $_[0]->{ type };
}
sub debug {
my $self = shift;
return $self->{ debug };
}
sub libxml {
my $self = shift;
return $self->{ libxml };
}
sub file {
my $self = shift;
my $params = @_ && ref $_[-1] eq 'HASH' ? pop(@_) : { };
my @args = @_;
push(@args, $params);
$params->{ libxml } = $self->{ libxml }
unless defined $params->{ libxml };
return $self->{ context }->plugin('XML.File', \@args);
}
sub dir {
die "dir() not yet implemented";
# pretty much as per file
}
sub dom {
my $self = shift;
# TODO: see if we've got a filename defined, create a DOM parser
# (and cache it), and then call its parse() method
# ...but for now, we'll just create a plugin
$self->{ context }->plugin('XML.DOM', \@_);
}
sub xpath {
my $self = shift;
# as above
$self->{ context }->plugin('XML.XPath', \@_);
}
sub rss {
my $self = shift;
# as above
$self->{ context }->plugin('XML.RSS', \@_);
}
sub simple {
my $self = shift;
# as above
$self->{ context }->plugin('XML.Simple', \@_ );
}
sub throw {
my $self = shift;
die $EXCEPTION->new( XML => join('', @_) );
}
sub detect_filehandle {
my $self = shift;
# look for a filehandle using Scalar::Utils openhandle if it's
# available or our poor-man's version if not.
return $OPENHANDLE ? openhandle($_[0]) : defined(fileno $_[0]);
}
sub detect_type {
my $self = shift;
# look for a filehandle using Scalar::Utils openhandle if it's
# available or our poor-man's version if not.
return 'fh' if $self->detect_filehandle($_[0]);
# okay, look for the xml declaration at the start
return 'xml_text' if $_[0] =~ m/^\<\?xml/;
# okay, look for the html declaration anywhere in the doc
return 'html_text' if $_[0] =~ m//i;
# okay, does this contain a "<" symbol, and declare it to be
# xml if it's got one, though they should use " module or L. For
information on using plugins, see L and
L. For further information
on XML, see L.
=head1 METHODS
The XML plugin module provides a number of methods to create various
other XML plugin objects.
=head2 file(name)
Creates a Template::Plugin::XML::File object. This is a subclass
of Template::Plugin::File.
=head2 dir(path)
Creates a Template::Plugin::XML::Directory object. This is a subclass
of Template::Plugin::Directory.
=head2 dom()
Generate a Document Object Module from an XML file. This can be
called against a directory, file or an XML plugin object, as long as
the source XML filename is defined somewhere along the line.
[% dom = XML.dom(filename) %]
[% file = XML.file(filename);
dom = file.dom
%]
[% dir = XML.dir(dirname);
dom = dir.dom(filename)
%]
=head2 xpath()
Perform XPath queries on the file. Like the dom() method, xpath() can
be called against a file, directory or an XML plugin object.
[% xpath = XML.xpath(filename) %]
[% file = XML.file(filename);
xpath = file.xpath
%]
[% dir = XML.dir(dirname);
xpath = dir.xpath(filename)
%]
=head2 simple()
TODO: As per dom() and xpath() but for XML::Simple
=head2 rss()
TODO: As per dom(), xpath() and simple() but for XML::RSS
=head1 XML PLUGINS
These are the XML plugins provided in this distribution.
=head2 Template::Plugin::XML
Front-end module to the XML plugin collection.
=head2 Template::Plugin::XML::File
This plugin module is used to represent individual XML files. It is a
subclass of the Template::Plugin::File module, providing the
additional dom(), xpath(), simple() and other methods relevant to XML
files.
=head2 Template::Plugin::XML::Directory
This plugin module is used to represent directories of XML files. It
is a subclass of the Template::Plugin::Directory module and provides
the same additional XML related methods as Template::Plugin::XML::File.
=head2 Template::Plugin::XML::DOM
Plugin interface providing access to the XML::DOM module.
[% USE XD = XML.Dom %]
[% dom = XD.parse_file('example.xml') %]
[% pages = dom.getElementsByTagName('page') %]
=head2 Template::Plugin::XML::RSS
Plugin interface providing access to the XML::RSS module.
[% USE news = XML.RSS('news.rdf') -%]
[% FOREACH item IN news.items -%]
* [% item.title %]
[% END %]
=head2 Template::Plugin::XML::Simple
Plugin interface providing access to the XML::Simple module.
[% USE xml = XML.Simple('example.xml') %]
=head2 Template::Plugin::XML::XPath
Plugin interface providing access to the XML::XPath module.
[% USE xpath = XML.XPath('example.xml');
bar = xpath.find('/foo/bar');
%]
=head1 AUTHORS
Andy Wardley wrote the Template Toolkit plugin modules, with
assistance from Simon Matthews in the case of the XML::DOM plugin.
Matt Sergeant wrote the XML::XPath module. Enno Derksen and Clark
Cooper wrote the XML::DOM module. Jonathan Eisenzopf wrote the
XML::RSS module. Grant McLean wrote the XML::Simple module. Clark
Cooper and Larry Wall wrote the XML::Parser module. James Clark wrote
the expat library.
=head1 COPYRIGHT
Copyright (C) 1996-2007 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.
=head1 SEE ALSO
L, L,
L, L,
L, L
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:
Template-XML-2.17/lib/Template/XML.pod 0000644 0001750 0001750 00000004303 10563113667 016715 0 ustar abw abw 0000000 0000000 =head1 NAME
Template::XML - XML plugins for the Template Toolkit
=head1 SYNOPSIS
[% USE XML;
dom = XML.dom('foo.xml');
xpath = XML.xpath('bar.xml');
simple = XML.simple('baz.xml');
rss = XML.simple('news.rdf');
%]
=head1 DESCRIPTION
The Template-XML distribution provides a number of Template Toolkit
plugin modules for working with XML.
The Template::Plugin::XML module is a front-end to the various other
XML plugin modules. Through this you can access XML files and
directories of XML files via the Template::Plugin::XML::File and
Template::Plugin::XML::Directory modules (which subclass from the
Template::Plugin::File and Template::Plugin::Directory modules
respectively). You can then create a Document Object Model (DOM) from
an XML file (Template::Plugin::XML::DOM), examine it using XPath
queries (Template::Plugin::XML::XPath), turn it into a Perl data
structure (Template::Plugin::XML::Simple) or parse it as an RSS (RDF
Site Summary) file.
The basic XML plugins were distributed as part of the Template Toolkit
until version 2.15 released in May 2006. At this time they were
extracted into this separate Template-XML distribution and an alpha
version of this Template::Plugin::XML front-end module was added.
=head1 AUTHORS
Andy Wardley wrote the Template Toolkit plugin modules, with
assistance from Simon Matthews in the case of the XML::DOM plugin.
Matt Sergeant wrote the XML::XPath module. Enno Derksen and Clark
Cooper wrote the XML::DOM module. Jonathan Eisenzopf wrote the
XML::RSS module. Grant McLean wrote the XML::Simple module. Clark
Cooper and Larry Wall wrote the XML::Parser module. James Clark wrote
the expat library.
=head1 COPYRIGHT
Copyright (C) 1996-2006 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.
=head1 SEE ALSO
L, L, L,
L, L,
L, L
=cut
# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4:
Template-XML-2.17/README 0000644 0001750 0001750 00000004173 10563113667 014115 0 ustar abw abw 0000000 0000000 NAME
Template::XML - XML plugins for the Template Toolkit
SYNOPSIS
[% USE XML;
dom = XML.dom('foo.xml');
xpath = XML.xpath('bar.xml');
simple = XML.simple('baz.xml');
rss = XML.simple('news.rdf');
%]
DESCRIPTION
The Template-XML distribution provides a number of Template Toolkit
plugin modules for working with XML.
The Template::Plugin::XML module is a front-end to the various other XML
plugin modules. Through this you can access XML files and directories of
XML files via the Template::Plugin::XML::File and
Template::Plugin::XML::Directory modules (which subclass from the
Template::Plugin::File and Template::Plugin::Directory modules
respectively). You can then create a Document Object Model (DOM) from an
XML file (Template::Plugin::XML::DOM), examine it using XPath queries
(Template::Plugin::XML::XPath), turn it into a Perl data structure
(Template::Plugin::XML::Simple) or parse it as an RSS (RDF Site Summary)
file.
The basic XML plugins were distributed as part of the Template Toolkit
until version 2.15 released in May 2006. At this time they were
extracted into this separate Template-XML distribution and an alpha
version of this Template::Plugin::XML front-end module was added.
AUTHORS
Andy Wardley wrote the Template Toolkit plugin modules, with assistance
from Simon Matthews in the case of the XML::DOM plugin. Matt Sergeant
wrote the XML::XPath module. Enno Derksen and Clark Cooper wrote the
XML::DOM module. Jonathan Eisenzopf wrote the XML::RSS module. Grant
McLean wrote the XML::Simple module. Clark Cooper and Larry Wall wrote
the XML::Parser module. James Clark wrote the expat library.
COPYRIGHT
Copyright (C) 1996-2006 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.
SEE ALSO
Template, Template::Plugins, Template::Plugin::XML,
Template::Plugin::XML::DOM, Template::Plugin::XML::RSS,
Template::Plugin::XML::Simple, Template::Plugin::XML::XPath
Template-XML-2.17/Makefile.PL 0000644 0001750 0001750 00000001233 10563113667 015201 0 ustar abw abw 0000000 0000000 #!/usr/bin/perl -w # -*- perl -*-
use strict;
use ExtUtils::MakeMaker;
my %opts = (
'NAME' => 'Template::XML',
'VERSION_FROM' => 'lib/Template/Plugin/XML.pm',
'PMLIBDIRS' => [ 'lib' ],
'PREREQ_PM' => {
'Template' => 2.15,
'XML::Parser' => 2.19,
'XML::DOM' => 1.27,
'XML::RSS' => 0.9,
'XML::XPath' => 1.0,
'XML::Simple' => 2.0,
},
);
if ($ExtUtils::MakeMaker::VERSION >= 5.43) {
$opts{ AUTHOR } = 'Andy Wardley ';
$opts{ ABSTRACT } = 'XML plugins for the Template Toolkit',
}
WriteMakefile( %opts );
Template-XML-2.17/META.yml 0000644 0001750 0001750 00000001044 10563116312 014466 0 ustar abw abw 0000000 0000000 # http://module-build.sourceforge.net/META-spec.html
#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
name: Template-XML
version: 2.17
version_from: lib/Template/Plugin/XML.pm
installdirs: site
requires:
Template: 2.15
XML::DOM: 1.27
XML::Parser: 2.19
XML::RSS: 0.9
XML::Simple: 2
XML::XPath: 1
distribution_type: module
generated_by: ExtUtils::MakeMaker version 6.17
Template-XML-2.17/MANIFEST 0000644 0001750 0001750 00000001001 10563113667 014351 0 ustar abw abw 0000000 0000000 lib/Template/Plugin/XML.pm
lib/Template/Plugin/XML/DOM.pm
lib/Template/Plugin/XML/File.pm
lib/Template/Plugin/XML/LibXML.pm
lib/Template/Plugin/XML/RSS.pm
lib/Template/Plugin/XML/Simple.pm
lib/Template/Plugin/XML/Style.pm
lib/Template/Plugin/XML/View.pm
lib/Template/Plugin/XML/XPath.pm
lib/Template/XML.pod
Makefile.PL
MANIFEST This list of files
META.yml
README
t/dom.t
t/domview.t
t/file.t
t/rss.t
t/test/xml/example.rdf
t/test/xml/testfile.xml
t/xml.t
t/xml/example.xml
t/xmlsimple.t
t/xmlstyle.t
t/xpath.t