File Coverage

blib/lib/XML/Saxon/XSLT2.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package XML::Saxon::XSLT2;
2              
3 1     1   20396 use 5.008;
  1         3  
  1         31  
4 1     1   6 use strict;
  1         1  
  1         24  
5              
6 1     1   5 use Carp;
  1         5  
  1         76  
7 1     1   875 use IO::Handle;
  1         7268  
  1         45  
8 1     1   7 use Scalar::Util qw[blessed];
  1         2  
  1         85  
9 1     1   1573 use XML::LibXML;
  0            
  0            
10              
11             our $VERSION = '0.007';
12             my $classpath;
13              
14             BEGIN
15             {
16             foreach my $path (qw(
17             /usr/share/java/saxon9he.jar
18             /usr/local/share/java/saxon9he.jar
19             /usr/share/java/saxonb.jar
20             /usr/local/share/java/saxonb.jar))
21             {
22             $classpath = $path if -e $path;
23             last if defined $classpath;
24             }
25              
26             require Inline;
27             }
28              
29             sub import
30             {
31             my ($class, @args) = @_;
32             shift @args
33             if @args && exists $args[0] && defined $args[0] && $args[0] =~ /^[\d\.\_]{1,10}$/;
34             Inline->import(Java => 'DATA', CLASSPATH=>$classpath, @args);
35             }
36              
37             sub new
38             {
39             my ($class, $xslt, $baseurl) = @_;
40             $xslt = $class->_xml($xslt);
41            
42             if ($baseurl)
43             {
44             return bless { 'transformer' => XML::Saxon::XSLT2::Transformer->new($xslt, $baseurl) }, $class;
45             }
46             else
47             {
48             return bless { 'transformer' => XML::Saxon::XSLT2::Transformer->new($xslt) }, $class;
49             }
50             }
51              
52             sub parameters
53             {
54             my ($self, %params) = @_;
55             $self->{'transformer'}->paramClear();
56             while (my ($k,$v) = each %params)
57             {
58             if (ref $v eq 'ARRAY')
59             {
60             (my $type, $v) = @$v;
61             my $func = 'paramAdd' . {
62             double => 'Double',
63             string => 'String',
64             long => 'Long',
65             'int' => 'Long',
66             integer => 'Long',
67             decimal => 'Decimal',
68             float => 'Float',
69             boolean => 'Boolean',
70             bool => 'Boolean',
71             qname => 'QName',
72             uri => 'URI',
73             date => 'Date',
74             datetime => 'DateTime',
75             }->{lc $type};
76             croak "$type is not a supported type"
77             if $func eq 'paramAdd';
78             $self->{'transformer'}->$func($k, $v);
79             }
80             elsif (blessed($v) && $v->isa('DateTime'))
81             {
82             $self->{'transformer'}->paramAddDateTime($k, "$v");
83             }
84             elsif (blessed($v) && $v->isa('Math::BigInt'))
85             {
86             $self->{'transformer'}->paramAddLong($k, $v->bstr);
87             }
88             elsif (blessed($v) && $v->isa('URI'))
89             {
90             $self->{'transformer'}->paramAddURI($k, "$v");
91             }
92             else
93             {
94             $self->{'transformer'}->paramAddString($k, "$v");
95             }
96             }
97             return $self;
98             }
99              
100             sub transform
101             {
102             my ($self, $doc, $type) = @_;
103             $type = ($type =~ /^(text|html|xhtml|xml)$/i) ? (lc $type) : 'default';
104             $doc = $self->_xml($doc);
105             return $self->{'transformer'}->transform($doc, $type);
106             }
107              
108             sub transform_document
109             {
110             my $self = shift;
111             my $r = $self->transform(@_);
112            
113             $self->{'parser'} ||= XML::LibXML->new;
114             return $self->{'parser'}->parse_string($r);
115             }
116              
117             sub messages
118             {
119             my ($self) = @_;
120             return @{ $self->{'transformer'}->messages };
121             }
122              
123             sub media_type
124             {
125             my ($self, $default) = @_;
126             return $self->{'transformer'}->media_type || $default;
127             }
128              
129             sub doctype_public
130             {
131             my ($self, $default) = @_;
132             return $self->{'transformer'}->doctype_public || $default;
133             }
134              
135             sub doctype_system
136             {
137             my ($self, $default) = @_;
138             return $self->{'transformer'}->doctype_system || $default;
139             }
140              
141             sub version
142             {
143             my ($self, $default) = @_;
144             return $self->{'transformer'}->version || $default;
145             }
146              
147             sub encoding
148             {
149             my ($self, $default) = @_;
150             return $self->{'transformer'}->encoding || $default;
151             }
152              
153             sub _xml
154             {
155             my ($proto, $xml) = @_;
156            
157             if (blessed($xml) && $xml->isa('XML::LibXML::Document'))
158             {
159             return $xml->toString;
160             }
161             elsif (blessed($xml) && $xml->isa('IO::Handle'))
162             {
163             local $/;
164             my $str = <$xml>;
165             return $str;
166             }
167             elsif (ref $xml eq 'GLOB')
168             {
169             local $/;
170             my $str = <$xml>;
171             return $str;
172             }
173            
174             return $xml;
175             }
176              
177             1;
178              
179             =head1 NAME
180              
181             XML::Saxon::XSLT2 - process XSLT 2.0 using Saxon 9.x.
182              
183             =head1 SYNOPSIS
184              
185             use XML::Saxon::XSLT2;
186            
187             # make sure to open filehandle in right encoding
188             open(my $input, '<:encoding(UTF-8)', 'path/to/xml') or die $!;
189             open(my $xslt, '<:encoding(UTF-8)', 'path/to/xslt') or die $!;
190            
191             my $trans = XML::Saxon::XSLT2->new($xslt, $baseurl);
192             my $output = $trans->transform($input);
193             print $output;
194            
195             my $output2 = $trans->transform_document($input);
196             my @paragraphs = $output2->getElementsByTagName('p');
197              
198             =head1 DESCRIPTION
199              
200             This module implements XSLT 1.0 and 2.0 using Saxon 9.x via L.
201              
202             It expects Saxon to be installed in either '/usr/share/java/saxon9he.jar'
203             or '/usr/local/share/java/saxon9he.jar'. Future versions should be more
204             flexible. The saxon9he.jar file can be found at L -
205             just dowload the latest Java release of Saxon-HE 9.x, open the Zip archive,
206             extract saxon9he.jar and save it to one of the two directories above.
207              
208             =head2 Import
209              
210             use XML::Saxon::XSLT2;
211              
212             You can include additional parameters which will be passed straight on to
213             Inline::Java, like this:
214              
215             use XML::Saxon::XSLT2 EXTRA_JAVA_ARGS => '-Xmx256m';
216              
217             The C function I be called. If you load this module without
218             importing it, it will not work. (Don't worry, it won't pollute your namespace.)
219              
220             =head2 Constructor
221              
222             =over 4
223              
224             =item C<< XML::Saxon::XSLT2->new($xslt, [$baseurl]) >>
225              
226             Creates a new transformation. $xslt may be a string, a file handle or an
227             L. $baseurl is an optional base URL for resolving
228             relative URL references in, for instance, Exsl:importE links.
229             Otherwise, the current directory is assumed to be the base. (For base URIs
230             which are filesystem directories, remember to include the trailing slash.)
231              
232             =back
233              
234             =head2 Methods
235              
236             =over 4
237              
238             =item C<< $trans->parameters($key=>$value, $key2=>$value2, ...) >>
239              
240             Sets transformation parameters prior to running the transformation.
241              
242             Each key is a parameter name.
243              
244             Each value is the parameter value. This may be a scalar, in which case
245             it's treated as an xs:string; a L object, which is treated as
246             an xs:dateTime; a L object, xs:anyURI; a L, xs:long;
247             or an arrayref where the first element is the type and the second the
248             value. For example:
249              
250             $trans->parameters(
251             now => DateTime->now,
252             madrid_is_capital_of_spain => [ boolean => 1 ],
253             price_of_fish => [ decimal => '1.99' ],
254             my_link => URI->new('http://example.com/'),
255             your_link => [ uri => 'http://example.net/' ],
256             );
257              
258             The following types are supported via the arrayref notation: float, double,
259             long (alias int, integer), decimal, bool (alias boolean), string, qname, uri,
260             date, datetime. These are case-insensitive.
261              
262             =item C<< $trans->transform($doc, [$output_method]) >>
263              
264             Run a transformation, returning the output as a string.
265              
266             $doc may be a string, a file handle or an L.
267              
268             $output_method may be 'xml', 'xhtml', 'html' or 'text' to override
269             the XSLT output method; or 'default' to use the output method specified
270             in the XSLT file. 'default' is the default. In the current release,
271             'default' is broken. :-(
272              
273             =item C<< $trans->transform_document($doc, [$output_method]) >>
274              
275             As per , but returns the output as an L.
276              
277             This method is slower than C.
278              
279             =item C<< $trans->messages >>
280              
281             Returns a list of string representations of messages output by
282             Exsl:messageE during the last transformation run.
283              
284             =item C<< $trans->media_type($default) >>
285              
286             Returns the output media type for the transformation.
287              
288             If the transformation doesn't specify an output type, returns the default.
289              
290             =item C<< $trans->doctype_public($default) >>
291              
292             Returns the output DOCTYPE public identifier for the transformation.
293              
294             If the transformation doesn't specify a doctype, returns the default.
295              
296             =item C<< $trans->doctype_system($default) >>
297              
298             Returns the output DOCTYPE system identifier for the transformation.
299              
300             If the transformation doesn't specify a doctype, returns the default.
301              
302             =item C<< $trans->version($default) >>
303              
304             Returns the output XML version for the transformation.
305              
306             If the transformation doesn't specify a version, returns the default.
307              
308             =item C<< $trans->encoding($default) >>
309              
310             Returns the output encoding for the transformation.
311              
312             If the transformation doesn't specify an encoding, returns the default.
313              
314             =back
315              
316             =head1 BUGS
317              
318             Please report any bugs to L.
319              
320             =head1 SEE ALSO
321              
322             L is probably more reliable in terms of easy installation on a
323             variety of platforms, and it allows you to define your own XSLT extension
324             functions. However, the libxslt library that it's based on only supports XSLT
325             1.0.
326              
327             This module uses L.
328              
329             L.
330              
331             =head1 AUTHOR
332              
333             Toby Inkster Etobyink@cpan.orgE.
334              
335             =head1 COPYRIGHT
336              
337             Copyright 2010-2012 Toby Inkster
338              
339             This library is free software; you can redistribute it and/or modify it
340             under the same terms as Perl itself.
341              
342             =cut
343              
344             __DATA__