12.6.3. Discussion
XML documents describe the content of data, but they
don't contain any information about how those data
should be displayed. However, when XML content is coupled with a
stylesheet described using XSL (eXtensible Stylesheet Language), the
content is displayed according to specific visual rules.
The glue between XML and XSL is XSLT, which stands for eXtensible
Stylesheet Language Transformations. These transformations apply the
series of rules enumerated in the stylesheet to your XML data. So,
just as PHP parses your code and combines it with user input to
create a dynamic page, an XSLT program uses XSL and XML to output a
new page that contains more XML, HTML, or any other format you can
describe.
$xml = 'data.xml';
$xsl = 'stylesheet.xsl';
$xslt = xslt_create( );
$results = xslt_process($xslt, $xml, $xsl);
You start by defining variables to store the filenames for the XML
data and the XSL stylesheet. They're the first two
parameters to the transforming function, xslt_process(
). If the fourth argument is missing, as it is here, or set
to NULL, the function returns the results.
Otherwise, it writes the resulting data to the filename passed:
xslt_process($xslt, $xml, $xsl, 'data.html');
If you want to provide your XML and XSL data from variables instead
of files, call xslt_process( ) with a fifth
parameter, which allows you to substitute string placeholders for
your files:
// grab data from database
$r = mysql_query("SELECT pages.page AS xml, templates.template AS xsl
FROM pages, templates
WHERE pages.id=$id AND templates.id=pages.template")
or die("$php_errormsg");
$obj = mysql_fetch_object($r);
$xml = $obj->xml;
$xsl = $obj->xsl;
// map the strings to args
$args = array('/_xml' => $xml,
'/_xsl' => $xsl);
$results = xslt_process($xslt, 'arg:/_xml', 'arg:/_xsl', NULL, $args);
When reading and writing files, Sablotron supports two types of URIs.
The PHP default is file:, so Sablotron looks for
the data on the filesystem. Sablotron also uses a custom URI of
arg:, which allows users to alternatively pass in
data using arguments. That's the feature used here.
In the previous example, the data for the XML and XSL comes from a
database, but, it can arrive from anywhere, such as a remote URL or
POSTed data. Once you've obtained the data, create
the $args array. This sets up mappings between the
argument names and the variable names. The keys of the associative
array are the argument names passed to xslt_process(
); the values are the variables holding the data. By
convention, /_xml and /_xsl are
the argument names; however, you can use others.
Then call xslt_process( ) and in place of
data.xml, use arg:/_xml, with
arg: being the string that lets the extension know
to look in the $args array. Because
you're passing in $args as the
fifth parameter, you need to pass NULL as the
fourth argument; this makes sure the function returns the results.
if (!$results) {
error_log('XSLT Error: #' . xslt_errno($xslt) . ': ' . xslt_error($xslt));
}
The xslt_error( ) function returns a formatted
message describing the error, while xslt_errno( )
provides a numeric error code.
To set up your own custom error handling code, register a function
using xslt_set_error_handler( ). If there are
errors, that function is automatically called instead of any built-in
error handler.
function xslt_error_handler($processor, $level, $number, $messages) {
error_log("XSLT Error: #$level");
}
xslt_set_error_handler($xslt, 'xslt_error_handler');
Finally, PHP cleans up any open XSLT processors when the request
ends, but here's how to manually close the processor
and free its memory: