File Coverage

blib/lib/XSLT/Cache.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package XSLT::Cache;
2              
3 1     1   548 use vars qw($VERSION);
  1         1  
  1         70  
4             $VERSION = 0.2;
5              
6 1     1   4 use strict;
  1         1  
  1         28  
7 1     1   2262 use XML::LibXML;
  0            
  0            
8             use XML::LibXSLT;
9             use File::Cache::Persistent;
10              
11             sub new {
12             my ($class, %args) = @_;
13              
14             my $cache = new File::Cache::Persistent(
15             prefix => $args{prefix} || undef,
16             timeout => $args{timeout} || 0,
17             reader => \&_read_xsl_file
18             );
19              
20             my $this = {
21             cache => $cache,
22             };
23             bless $this, $class;
24              
25             return $this;
26             }
27              
28             sub transform {
29             my ($this, $xmldoc, $xsltpath) = @_;
30              
31             $xmldoc = $this->_get_xmldocument($xmldoc) unless ref $xmldoc && $xmldoc->isa("XML::LibXML::Document");
32             $xsltpath = $this->_get_xsltpath($xmldoc) unless $xsltpath;
33              
34             die "No path to XSLT specified\n" unless $xsltpath;
35            
36             $xsltpath = $this->{prefix} . '/' . $xsltpath if $this->{prefix};
37             my $xsldoc = $this->{cache}->get($xsltpath);
38              
39             return $xsldoc->output_string($xsldoc->transform($xmldoc));
40             }
41              
42             sub status {
43             my $this = shift;
44            
45             return $this->{cache}->status();
46             }
47              
48             sub _get_xmldocument {
49             my ($this, $xmldoc) = @_;
50              
51             my $xmlparser = new XML::LibXML();
52              
53             die "Empty XML document passed\n" unless $xmldoc;
54              
55             if ($xmldoc =~ /^<\?xml/) {
56             $xmldoc = $xmlparser->parse_string($xmldoc);
57             }
58             elsif (-f $xmldoc) {
59             $xmldoc = $xmlparser->parse_file($xmldoc);
60             }
61             else {
62             die "Cannot open XML File '$xmldoc'\n";
63             }
64             }
65              
66             sub _get_xsltpath {
67             my ($this, $xmldoc) = @_;
68              
69             my @stylesheet = $xmldoc->findnodes("processing-instruction('xml-stylesheet')");
70             if (@stylesheet) {
71             my $stylesheet = $stylesheet[0]->nodeValue;
72             if ($stylesheet =~ m{type\s*=\s*['"]text/xslt?['"]}) {
73             my ($href) = $stylesheet =~ m{href\s*=\s*['"](.*?)['"]};
74             return $href;
75             }
76             }
77              
78             return undef;
79             }
80              
81             sub _read_xsl_file {
82             my $path = shift;
83              
84             my $xslparser = new XML::LibXSLT();
85              
86             return $xslparser->parse_stylesheet_file($path);
87             }
88              
89             1;
90              
91             __END__