Recipe14.16.Using XSLT from Perl


Recipe 14.16. 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 front ends 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 13.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 front end 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 more 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 front end 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 Apache's AxKit (http://axkit.org), 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.




XSLT Cookbook
XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition
ISBN: 0596009747
EAN: 2147483647
Year: 2003
Pages: 208
Authors: Sal Mangano

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net