This file is indexed.

/usr/share/perl5/XML/Saxon/XSLT2.pm is in libxml-saxon-xslt2-perl 0.010-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
use 5.008;
use strict;
use warnings;
## skip Test::Tabs

package XML::Saxon::XSLT2;

use Carp;
use IO::Handle;
use Scalar::Util qw[blessed];
use XML::LibXML;

our $AUTHORITY = 'cpan:TOBYINK';
our $VERSION   = '0.010';

my $classpath;

BEGIN
{
	foreach my $path (qw(
		/usr/share/java/saxon9he.jar
		/usr/local/share/java/saxon9he.jar
		/usr/share/java/saxonb.jar
		/usr/local/share/java/saxonb.jar
		/usr/local/share/java/classes/saxon9he.jar
		/usr/share/java/Saxon-HE.jar
	)) {
		$classpath = $path if -e $path;
		last if defined $classpath;
	}

	require Inline;
}

sub import
{
	my ($class, @args) = @_;
	shift @args
		if @args && exists $args[0] && defined $args[0] && $args[0] =~ /^[\d\.\_]{1,10}$/;
	Inline->import( Java => 'DATA', CLASSPATH => $classpath, @args );
}

sub new
{
	my ($class, $xslt, $baseurl) = @_;
	$xslt = $class->_xml($xslt);
	
	if ($baseurl)
	{
		return bless { 'transformer' => XML::Saxon::XSLT2::Transformer->new($xslt, $baseurl) }, $class;
	}
	else
	{
		return bless { 'transformer' => XML::Saxon::XSLT2::Transformer->new($xslt) }, $class;
	}
}

sub parameters
{
	my ($self, %params) = @_;
	$self->{'transformer'}->paramClear();
	while (my ($k,$v) = each %params)
	{
		if (ref $v eq 'ARRAY')
		{
			(my $type, $v) = @$v;
			my $func = 'paramAdd' . {
				double    => 'Double',
				string    => 'String',
				long      => 'Long',
				'int'     => 'Long',
				integer   => 'Long',
				decimal   => 'Decimal',
				float     => 'Float',
				boolean   => 'Boolean',
				bool      => 'Boolean',
				qname     => 'QName',
				uri       => 'URI',
				date      => 'Date',
				datetime  => 'DateTime',
				}->{lc $type};
			croak "$type is not a supported type"
				if $func eq 'paramAdd';
			$self->{'transformer'}->$func($k, $v);
		}
		elsif (blessed($v) && $v->isa('DateTime'))
		{
			$self->{'transformer'}->paramAddDateTime($k, "$v");
		}	
		elsif (blessed($v) && $v->isa('Math::BigInt'))
		{
			$self->{'transformer'}->paramAddLong($k, $v->bstr);
		}
		elsif (blessed($v) && $v->isa('URI'))
		{
			$self->{'transformer'}->paramAddURI($k, "$v");
		}	
		else
		{
			$self->{'transformer'}->paramAddString($k, "$v");
		}
	}
	return $self;
}

sub transform
{
	my ($self, $doc, $type) = @_;
	$type = ($type =~ /^(text|html|xhtml|xml)$/i) ? (lc $type) : 'default';
	$doc  = $self->_xml($doc);
	return $self->{'transformer'}->transform($doc, $type);
}

sub transform_document
{
	my $self = shift;
	my $r    = $self->transform(@_);
	
	$self->{'parser'} ||= XML::LibXML->new;
	return $self->{'parser'}->parse_string($r);
}

sub messages
{
	my ($self) = @_;
	return @{ $self->{'transformer'}->messages };
}

sub media_type
{
	my ($self, $default) = @_;
	return $self->{'transformer'}->media_type || $default;
}

sub doctype_public
{
	my ($self, $default) = @_;
	return $self->{'transformer'}->doctype_public || $default;
}

sub doctype_system
{
	my ($self, $default) = @_;
	return $self->{'transformer'}->doctype_system || $default;
}

sub version
{
	my ($self, $default) = @_;
	return $self->{'transformer'}->version || $default;
}

sub encoding
{
	my ($self, $default) = @_;
	return $self->{'transformer'}->encoding || $default;
}

sub _xml
{
	my ($proto, $xml) = @_;
	
	if (blessed($xml) && $xml->isa('XML::LibXML::Document'))
	{
		return $xml->toString;
	}
	elsif (blessed($xml) && $xml->isa('IO::Handle'))
	{
		local $/;
		my $str = <$xml>;
		return $str;
	}
	elsif (ref $xml eq 'GLOB')
	{
		local $/;
		my $str = <$xml>;
		return $str;
	}
	
	return $xml;
}

1;

=head1 NAME

XML::Saxon::XSLT2 - process XSLT 2.0 using Saxon 9.x.

=head1 SYNOPSIS

 use XML::Saxon::XSLT2;
 
 # make sure to open filehandle in right encoding
 open(my $input, '<:encoding(UTF-8)', 'path/to/xml') or die $!;
 open(my $xslt, '<:encoding(UTF-8)', 'path/to/xslt') or die $!;
 
 my $trans  = XML::Saxon::XSLT2->new($xslt, $baseurl);
 my $output = $trans->transform($input);
 print $output;
 
 my $output2 = $trans->transform_document($input);
 my @paragraphs = $output2->getElementsByTagName('p');

=head1 DESCRIPTION

This module implements XSLT 1.0 and 2.0 using Saxon 9.x via L<Inline::Java>.

It expects Saxon to be installed in either '/usr/share/java/saxon9he.jar'
or '/usr/local/share/java/saxon9he.jar'. Future versions should be more
flexible. The saxon9he.jar file can be found at L<http://saxon.sourceforge.net/> -
just dowload the latest Java release of Saxon-HE 9.x, open the Zip archive,
extract saxon9he.jar and save it to one of the two directories above.

=head2 Import

 use XML::Saxon::XSLT2;

You can include additional parameters which will be passed straight on to
Inline::Java, like this:

 use XML::Saxon::XSLT2 EXTRA_JAVA_ARGS => '-Xmx256m';

The C<import> function I<must> be called. If you load this module without
importing it, it will not work. (Don't worry, it won't pollute your namespace.)

=head2 Constructor

=over 4

=item C<< XML::Saxon::XSLT2->new($xslt, [$baseurl]) >>

Creates a new transformation. $xslt may be a string, a file handle or an
L<XML::LibXML::Document>. $baseurl is an optional base URL for resolving
relative URL references in, for instance, E<lt>xsl:importE<gt> links.
Otherwise, the current directory is assumed to be the base. (For base URIs
which are filesystem directories, remember to include the trailing slash.)

=back

=head2 Methods

=over 4

=item C<< $trans->parameters($key=>$value, $key2=>$value2, ...) >>

Sets transformation parameters prior to running the transformation.

Each key is a parameter name.

Each value is the parameter value. This may be a scalar, in which case
it's treated as an xs:string; a L<DateTime> object, which is treated as
an xs:dateTime; a L<URI> object, xs:anyURI; a L<Math::BigInt>, xs:long;
or an arrayref where the first element is the type and the second the
value. For example:

 $trans->parameters(
    now             => DateTime->now,
    madrid_is_capital_of_spain => [ boolean => 1 ],
    price_of_fish   => [ decimal => '1.99' ],
    my_link         => URI->new('http://example.com/'),
    your_link       => [ uri => 'http://example.net/' ],
 );

The following types are supported via the arrayref notation: float, double,
long (alias int, integer), decimal, bool (alias boolean), string, qname, uri,
date, datetime. These are case-insensitive.

=item C<< $trans->transform($doc, [$output_method]) >>

Run a transformation, returning the output as a string.

$doc may be a string, a file handle or an L<XML::LibXML::Document>.

$output_method may be 'xml', 'xhtml', 'html' or 'text' to override
the XSLT output method; or 'default' to use the output method specified
in the XSLT file. 'default' is the default. In the current release,
'default' is broken. :-(

=item C<< $trans->transform_document($doc, [$output_method]) >>

As per <transform>, but returns the output as an L<XML::LibXML::Document>.

This method is slower than C<transform>.

=item C<< $trans->messages >>

Returns a list of string representations of messages output by
E<lt>xsl:messageE<gt> during the last transformation run.

=item C<< $trans->media_type($default) >>

Returns the output media type for the transformation.

If the transformation doesn't specify an output type, returns the default.

=item C<< $trans->doctype_public($default) >>

Returns the output DOCTYPE public identifier for the transformation.

If the transformation doesn't specify a doctype, returns the default.

=item C<< $trans->doctype_system($default) >>

Returns the output DOCTYPE system identifier for the transformation.

If the transformation doesn't specify a doctype, returns the default.

=item C<< $trans->version($default) >>

Returns the output XML version for the transformation.

If the transformation doesn't specify a version, returns the default.

=item C<< $trans->encoding($default) >>

Returns the output encoding for the transformation.

If the transformation doesn't specify an encoding, returns the default.

=back

=head1 BUGS

Please report any bugs to L<http://rt.cpan.org/>.

=head1 SEE ALSO

L<XML::LibXSLT> is probably more reliable in terms of easy installation on a
variety of platforms, and it allows you to define your own XSLT extension
functions. However, the libxslt library that it's based on only supports XSLT
1.0.

This module uses L<Inline::Java>.

L<http://saxon.sourceforge.net/>.

=head1 AUTHOR

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

=head1 COPYRIGHT

Copyright 2010-2012, 2014 Toby Inkster

This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

__DATA__
__Java__
import net.sf.saxon.s9api.*;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;
import org.w3c.dom.Document;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLFilterImpl;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.OutputKeys;
import java.io.*;
import java.math.BigDecimal;
import java.net.URI;
import java.util.*;

public class Transformer
{
	private XsltExecutable xslt;
	private Processor proc;
	private HashMap<String, XdmAtomicValue> params;
	public List messagelist;

	public Transformer (String stylesheet)
		throws SaxonApiException
	{
		proc = new Processor(false);
		XsltCompiler comp = proc.newXsltCompiler();
		xslt = comp.compile(new StreamSource(new StringReader(stylesheet)));
		params = new HashMap<String, XdmAtomicValue>();
		messagelist = new ArrayList();
	}
	
	public Transformer (String stylesheet, String baseuri)
		throws SaxonApiException
	{
		proc = new Processor(false);
		XsltCompiler comp = proc.newXsltCompiler();
		xslt = comp.compile(new StreamSource(new StringReader(stylesheet), baseuri));
		params = new HashMap<String, XdmAtomicValue>();
		messagelist = new ArrayList();
	}
	
	public void paramAddString (String key, String value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddLong (String key, long value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddDecimal (String key, BigDecimal value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddFloat (String key, float value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddDouble (String key, double value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddBoolean (String key, boolean value)
	{
		params.put(key, new XdmAtomicValue(value));
	}

	public void paramAddURI (String key, String value)
		throws java.net.URISyntaxException
	{
		params.put(key, new XdmAtomicValue(new URI(value.toString())));
	}

	public void paramAddQName (String key, String value)
	{
		params.put(key, new XdmAtomicValue(new QName(value.toString())));
	}

	public void paramAddDate (String key, String value)
		throws SaxonApiException
	{
		ItemTypeFactory itf = new ItemTypeFactory(proc);
		ItemType dateType = itf.getAtomicType(new QName("http://www.w3.org/2001/XMLSchema", "date"));
		params.put(key, new XdmAtomicValue(value, dateType));
	}

	public void paramAddDateTime (String key, String value)
		throws SaxonApiException
	{
		ItemTypeFactory itf = new ItemTypeFactory(proc);
		ItemType dateTimeType = itf.getAtomicType(new QName("http://www.w3.org/2001/XMLSchema", "datetime"));
		params.put(key, new XdmAtomicValue(value, dateTimeType));
	}

	public XdmAtomicValue paramGet (String key)
	{
		return params.get(key);
	}

	public void paramRemove (String key)
	{
		params.remove(key);
	}
	
	public void paramClear ()
	{
		params.clear();
	}
	
	public Object[] messages ()
	{
		return messagelist.toArray();
	}
	
	public String media_type ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.MEDIA_TYPE);
	}

	public String doctype_public ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.DOCTYPE_PUBLIC);
	}

	public String doctype_system ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.DOCTYPE_SYSTEM);
	}

	public String method ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.METHOD);
	}

	public String version ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.VERSION);
	}

	public String standalone ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.STANDALONE);
	}

	public String encoding ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.ENCODING);
	}

	public String indent ()
	{
		return xslt.getUnderlyingCompiledStylesheet().getOutputProperties().getProperty(OutputKeys.INDENT);
	}

	public String transform (String doc, String method)
		throws SaxonApiException
	{
		XdmNode source = proc.newDocumentBuilder().build(
			new StreamSource(new StringReader(doc))
			);

		XsltTransformer trans = xslt.load();
		trans.setInitialContextNode(source);

		Serializer out = new Serializer();
		StringWriter sw = new StringWriter();
		out.setOutputWriter(sw);
		trans.setDestination(out);

		if (!method.equals("default"))
		{
			out.setOutputProperty(Serializer.Property.METHOD, method);
		}

		Iterator i = params.keySet().iterator();
		while (i.hasNext())
		{
			Object k = i.next();
			XdmAtomicValue v = params.get(k);
			
			trans.setParameter(new QName(k.toString()), v);
		}

		messagelist.clear();
		trans.setMessageListener(
			new MessageListener() {
				public void message(XdmNode content, boolean terminate, SourceLocator locator) {
					messagelist.add(content.toString());
				}
			}
		);
		
		trans.transform();
				
		return sw.toString();
	}
}