Using XSLT from Perl

Problem

You have a problem that is more appropriately solved in Perl, but would be easier with a pinch of XSLT.

Solution

There are several choices for embedding XSLT in Perl. XML::LibXSLT and XML::LibXML are Perl frontends to the functionality of GNOME library’s SAX and XSLT processors. The following example, borrowed from Erik T. Ray’s and Jason McIntosh’s Perl and XML (O’Reilly, 2002), shows a Perl program that batch-processes several XML files with a single XSLT script, compiled once:

use XML::LibXSLT;
use XML::LibXML;
   
# the arguments for this command are stylesheet and source files
my( $style_file, @source_files ) = @ARGV;
   
# initialize the parser and XSLT processor
my $parser = XML::LibXML->new(  );
my $xslt = XML::LibXSLT->new(  );
my $stylesheet = $xslt->parse_stylesheet_file( $style_file );
   
# for each source file: parse, transform, print out result
foreach my $file ( @source_files ) {
  my $source_doc = $parser->parse_file( $source_file );
  my $result = $stylesheet->transform( $source_doc );
  print $stylesheet->output_string( $result );
}

Parameters to the stylesheet can be passed in as a Perl hash, as shown in the following code:

               #Similar code from previous example has been elided.
   
my %params = {
               param1 => 10,
    param2 => 'foo',
} ;
   
foreach my $file ( @source_files ) {
  my $source_doc = $parser->parse_file( $file );
  my $result = $stylesheet->transform($source_doc, %params);
  print $stylesheet->output_string( $result );
}

Passing parameters to from Perl to the stylesheet would enable, among other things, a Perl-based CGI program that received input from an HTML form and queried an XML database using XSLT. See Recipe 11.5, where we cheated by forking the XSLT processor rather than embedding.

XML::Xalan is another Perl XSLT module that allows Perl to invoke Xalan’s processor. Edwin Pratomo, the author of this module, still considers it alpha-level software.

Using XML::Xalan through external files is your simplest option:

use XML::Xalan;
   
  #Construct the transformer
  my $tr = new XML::Xalan::Transformer;
   
  #Compile the stylesheet
  my $compiled = $tr->compile_stylesheet_file("my.xsl");
  
#Parse the input source document
  my $parsed = $tr->parse_file("my.xml");
   
  my $dest_file = "myresult.xml" ;
   
  #Execute the transformation saving the result
  $tr->transform_to_file($parsed, $compiled, $dest_file)
    or die $tr->errstr;

A more useful mode of usage returns the result into a variable for further processing:

my $res = $tr->transform_to_data($parsed, $compiled);

You do not need to preparse the input or precompile the stylesheet, since either can be passed as files or literal strings:

my $res = $tr->transform_to_data($src_file, $xsl_file);

This returns the literal result as a string, so this usage probably makes most sense when the output format is text that you want to post-process in Perl.

Alternatively, you can receive the results in an event-driven manner:

#Create a handler sub
$out_handler = sub {
     my ($ctx, $mesg) = @_;
     print $ctx $mesg;
 };
#Invoke the transformation using the handler
$tr->transform_to_handler(
     $xmlfile, $xslfile, 
     *STDERR, $out_handler);

Discussion

Many Perl developers have not fully embraced XSLT because once you master Perl, it is difficult to do something in anything but the Perl way. To be fair, most Perl developers realize that other languages have their place, and XSLT certainly can simplify a complex XML transformation even if most of the overall program remains purely Perl.

See Also

Other Perl XSLT solutions include T. J. Mather’s XML::GNOME::XSLT, which is a Perl frontend to libXSLT, a C-based XSLT processor from GNOME. You can also use the native Perl XSLT implementation XML::XSLT by Jonathan Stowe. Currently, it does not implement many of XSLT 1.0’s most advanced features, including xsl:sort, xsl:key, and xsl:import, and it has only partial support in several other areas. A third option is Pavel Hlavnicka’s XML::Saboltron, which is a Perl frontend to the Ginger Alliance’s C++-based XSLT offering. Information on these modules can be found at http://www.cpan.org.

Another solution that mixes Perl with XSLT is AxKit, an XML Application server for Apache. AxKit uses a pipelining processing model that allows processing of content in stages. It uses the Sablotron processor for XSLT functionality.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.199.162