xslt_process

(PHP 4 >= 4.0.3)

xslt_processFührt eine XSLT-Transformation durch

Beschreibung

mixed xslt_process ( resource $xh , string $xmlcontainer , string $xslcontainer [, string $resultcontainer [, array $arguments [, array $parameters ]]] )

Die Funktion xslt_process() ist die Krux der XSLT-Extension. Sie erlaubt es Ihnen, eine XSLT-Transformation unter Verwendung von fast jeder Art von Eingabequelle durchzuführen - den Containern. Dies wird durch die Verwendung von Argument-Buffern erreicht, einem Konzept, das vom Sablotron-XSLT-Prozessor übernommen wurde (derzeit der einzige XSLT-Prozessor, den diese Extension unterstützt). Die Input-Container enthalten standardmäßig einen Dateinamen, der für die zu prozessierende Datei steht.

Parameter-Liste

xh

Der XSLT-Prozessor-Linkidentifier, der mittels xslt_create() erzeugt wurde.

xmlcontainer

Pfad zur XML-Datei oder Platzhalter für ein XML-Argument.

xslcontainer

Pfad zur XSL-Datei oder Platzhalter für ein XML-Argument.

resultcontainer

Der Result-Container enthält standardmäßig den Dateinamen des transformierten Dokuments. Wenn der Result-Container nicht angegeben wurde (also NULL ist), wird das Ergebnis zurückgegeben.

arguments

Anstelle von Dateien können Sie auch "Argument-Platzhalter" als XML- oder XSLT-Argumente an xslt_process() übergeben. Diese Platzhalter werden durch die im arguments-Array angegebenen Werte ersetzt.

parameters

Ein Array von aller Toplevel-Parameter, die an das XSLT-Dokument übergeben werden sollen. Auf diese Parameter können Sie in Ihren XSL-Dateien unter Verwendung einer <xsl:param name="parameter_name">-Anweisung zugreifen. Die Parameter müssen UTF-8-kodiert sein, ihre Werte werden vom Sablotron-Prozessor als Strings interpretiert. Mit anderen Worten, Sie können keine Node-Sets als Parameter an ein XSLT-Dokument übergeben.

Container können außerdem mittels des arguments-Arrays bestimmt werden (siehe unten).

Rückgabewerte

Gibt bei Erfolg TRUE zurück. Im Fehlerfall wird FALSE zurückgegeben. Wenn der Result-Container nicht angegeben wurde (also z.B. NULL ist), wird das Ergebnis zurückgegeben.

Changelog

Version Beschreibung
4.0.6 Die Funktion akzeptiert nicht länger Strings in xmlcontainer und xslcontainer. Die Übergabe von XML-enthaltenden Zeichenketten an einen der beiden Parameter erzeugt einen Speicherzugriffsfehler in Sablotronversionen bis inklusive 0.95.

Beispiele

Die einfachste Art einer Transformation mit der xslt_process()-Funktion ist die Transformation eines XML-Files durch ein XSLT-File und die Speicherung des Ergebnisses in eine dritte Datei, die das neue XML- (oder HTML-)Dokument enthält. Dies mit Sablotron zu tun ist mehr als einfach.

Beispiel #1 Verwendung von xslt_process(), um eine XML-Datei und eine XSL-Datei in ein neues XML-File zu transformieren

<?php

// Einen neuen XSLT-Prozessor erstellen
$xh xslt_create();

// Das Dokument verarbeiten
if (xslt_process($xh'sample.xml''sample.xsl''result.xml')) {
    echo 
"ERFOLG, sample.xml wurde durch sample.xsl in result.xml transformiert";
    echo 
", result.xml hat folgenden Inhalt\n<br />\n";
    echo 
"<pre>\n";
    
readfile('result.xml');
    echo 
"</pre>\n";
} else {
    echo 
"Sorry, sample.xml konnte nicht von sample.xsl in result.xml ";
    echo 
"transformiert werden. Fehlermeldung: " xslt_error($xh) . " und ";
    echo 
"Fehlernummer: " xslt_errno($xh);
}

xslt_free($xh);

?>

Obwohl diese Funktion in den meisten Fällen, besonders im Webumfeld, hervorragend läuft, sollten Sie dennoch davon absehen, Ihre Ergebnisse direkt auszugeben. Daher ist es geschickter, das dritte Argument der xslt_process()-Funktion wegzulassen (oder dem Argument NULL zu übergeben) und damit den Rückgabewert der XSLT-Transformation zu erhalten, statt ihn in eine Datei zu schreiben.

Beispiel #2 Verwendung von xslt_process(), um eine XML-Datei und eine XSL-Datei zu transformieren und einer Variable die resultierenden XML-Daten zuzuweisen

<?php

// Einen neuen XSLT-Prozessor erstellen
$xh xslt_create();

// Dokument verarbeiten, Rückgabe des Ergebnisses an die $result-Variable
$result xslt_process($xh'sample.xml''sample.xsl');
if (
$result) {
    echo 
"ERFOLG, sample.xml wurde durch sample.xsl in die Variable \$result ";
    echo 
"transformiert, die Variable \$result hat folgenden Inhalt\n<br />\n";
    echo 
"<pre>\n";
    echo 
$result;
    echo 
"</pre>\n";
} else {
    echo 
"Sorry, sample.xml konnte nicht von sample.xsl in die Variable \$result ";
    echo 
"transformiert werden. Fehlermeldung: " xslt_error($xh) . " und ";
    echo 
"Fehlernummer: " xslt_errno($xh);
}

xslt_free($xh);

?>

Die oberen zwei Fälle sind die einfachsten Fälle die es gibt, wenn eine XSLT-Transformation durchgeführt werden soll. Unseres Erachtens sind sie sogar die häufigsten Fälle; allerdings erhalten Sie auch häufig Ihr XML- und XSLT-Daten aus externen Quellen wie Datenbanken oder Sockets. In diesen Fällen befinden sich die XML- und/oder die XSLT-Daten in einer Variablen - und in Anwendungen, die produktiv eingesetzt werden, erzeugt es zu viel Overhead, diese Daten vor ihrer Verarbeitung erst in eine Datei zu schreiben. An dieser Stelle kommt die XSLT-"argument"-Syntax zum Tragen. Anstatt Dateien als XML- und XSLT-Argumente an xslt_process() zu übergeben, können Sie "Argumentplatzhalter" angeben, die durch die im Argument-Array übergebenen Werte ersetzt werden (der fünfte Parameter der Funktion xslt_process()). Nachfolgend zeigen wir in einem Beispiel, wie XML und XSLT verarbeitet und das Ergebnis in eine Variable geschrieben wird, ohne eine Datei zu verwenden.

Beispiel #3 Verwendung von xslt_process(), um eine XML-Daten enthaltende Variable und eine XSL-Daten enthaltende Variable in eine Variable zu transformieren, die die resultierenden XML-Daten enthält

<?php
// $xml und $xsl enthalten die XML- und XSL-Daten

$arguments = array(
     
'/_xml' => $xml,
     
'/_xsl' => $xsl
);

// Einen neuen XSLT-Prozessor erzeugen
$xh xslt_create();

// Dokument verarbeiten
$result xslt_process($xh'arg:/_xml''arg:/_xsl'NULL$arguments);
if (
$result) {
    echo 
"ERFOLG, sample.xml wurde durch sample.xsl in die Variable \$result ";
    echo 
"transformiert, die Variable \$result hat folgenden Inhalt\n<br />\n";
    echo 
"<pre>\n";
    echo 
$result;
    echo 
"</pre>\n";
} else {
    echo 
"Sorry, sample.xml konnte nicht von sample.xsl in die Variable \$result ";
    echo 
"transformiert werden. Fehlermeldung: " xslt_error($xh) . " und ";
    echo 
"Fehlernummer: " xslt_errno($xh);
}
xslt_free($xh);
?>

Beispiel #4 PHP-Variablen an die XSL-Dateien übergeben

<?php

// XML-String
$xml '<?xml version="1.0"?>
<para>
 ändere mich
</para>'
;

// XSL-String
$xsl '
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="ISO-8859-1" indent="no"
 omit-xml-declaration="yes"  media-type="text/html"/>
 <xsl:param name="myvar"/>
 <xsl:param name="mynode"/>
 <xsl:template match="/">
Meine PHP-Variable: <xsl:value-of select="$myvar"/><br />
Mein Node-Set: <xsl:value-of select="$mynode"/>
 </xsl:template>
</xsl:stylesheet>'
;


$xh xslt_create();

// der zweite Parameter wird als String interpretiert
$parameters = array (
  
'myvar' => 'test',
  
'mynode' => '<foo>bar</foo>'
);

$arguments = array (
  
'/_xml' => $xml,
  
'/_xsl' => $xsl
);

echo 
xslt_process($xh'arg:/_xml''arg:/_xsl'NULL$arguments$parameters);

?>

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Meine PHP-Variable: test<br>
Mein Node-Set: &lt;foo&gt;bar&lt;/foo&gt;

Anmerkungen

Hinweis:

Wenn Sie Windows verwenden, beachten Sie bitte, vor Pfadangaben file:// zu schreiben.

add a note add a note

User Contributed Notes 30 notes

up
0
anonymous
6 years ago
It is possible that the xslt_process call can expose information about Apache's installation location if null values are passed to the signature.

for example:
<?php
$xslt
= xslt_create();
$result = xslt_process($xslt, null, null);
echo
$result;
?>

The error you will recieve is:
Warning:  Sablotron error on line none: cannot open file 'C:\Program Files\Apache Group\Apache2/' in C:\webroot\htdocs\projects\www\sales\test.php on line 4

Although trying to read a 'null' XML file and 'null' XSL stylesheet are rather silly, consider an attacker tries to upload an arbitrary file and execute it with similar code.

the user may then gain enough information to attack your site.
up
0
Anonymous
7 years ago
To let xslt_process() work correctly, you have to set xslt_set_base()
Here is my example code (Tested on: Windows 2000/XAMPP 1.4.15/PHP 4.4.0/Sablotron 1.0.2):

<?php
$xh
= xslt_create();
$filebase = 'file://' . getcwd () . '/test/';
xslt_set_base($xh,$filebase);
   
$xml = 'document.xml';
$xsl = 'document.xsl';
$resultdoc = 'result.html';
   
$parameters = array('mynode' => '<foo>bar</foo>','sample' => 'A sample value');

$result = xslt_process($xh,$xml,$xsl,$resultdoc,NULL,$parameters);
if (!
$result)
{
    die(
sprintf("Cannot process XSLT document [%d]: %s",xslt_errno($xh), xslt_error($xh)));
}
echo
"Result: ".$result."<br />";
xslt_free($xh);
?><a href="test/<?=$resultdoc?>">The result document</a><?
?>
up
0
ken at guest dot ie
8 years ago
After experiencing an ”xml declaration not at start of external entity” error with XML recieved from a remote server. The server now sends response headers back and these were getting in the way.

This fixed it:

$fp = fsockopen($queryhost, 80);
if($fp) {
    fputs($fp, $header);
    while(!feof($fp)) {
        $xml .= fgets($fp, 128);
    }
}
fclose($fp);

//ensure string starts with the XML declaration.
$xml = substr($xml, strpos($xml, “<?xml”) );

$xsltproc = xslt_create();
$result = xslt_process($xsltproc,‘arg:/_xml’, $xsltfile, NULL, array(/_xml’ => $xml));
up
0
Anonymous
8 years ago
just to let you know an an apostrophe   can generate a  "not well-formed (invalid token)" error message. I spent a couple of hours to find it, until i found another user with similar problem:
http://www.feedforall.com/forum/viewtopic.php?t=116&view=next
lets hope that hosting providers will soon adopt php5
up
0
csarven at gmail dot com
9 years ago
I found using the output buffer to be efficient, when dealing with php scripts, with xml data.

<?
$xh
= xslt_create();

ob_start();
include(
'main.php');          //main.php contains php and xml
$xml_file = ob_get_contents();
ob_end_clean();

$arguments = array('/_xml' => $xml_file);

$result = xslt_process($xh, 'arg:/_xml', 'index.xsl', NULL, $arguments);

if (!
$result) echo 'XSLT processing error: ' .xslt_error($xh) ;
else echo
$result;

xslt_free($xh);
?>
up
0
ppekaar at hotmail dot com
9 years ago
In response to "twa at carlbro dot dk" above I have finally solved how to combine two XML sources and one XSL stylesheet.  The above comment was nearly right,

for the php

<?php

xh
= xslt_create();
xslt_set_base($xh,"file://c:\inetpub\wwwroot\yourwebsite\");

$arguments = array('/_xml' => $xmlSingle, '/_xsl'=>$xsl, '/xml2'=>$xml_rates);
$xslResult = xslt_process($xh, 'arg:/_xml', 'single_availability_filter.xsl', NULL, $arguments,$parameters);

?>

Please note that I have put in a blank variable "
/_xsl => $xsl", the actuall XSL file is listed directly in the xslt_process fucntion.

Note that we have a third XML data source which is called xml2 and is set a value
$xml_rates.  In your XSL stylesheet you can now call this XML data via the following line

<xsl:variable name="
filter_rates" select="document('arg:/xml2')/RackRates"/>

the missing link was putting in the the arg:/

Also please note that I am using xslt_set_base which set the base filepath for all your XSL documents.

Hope this helps. 
Phelim
up
0
Justin Ramos
9 years ago
The xslt_ functions no longer work in PHP/5.0; the XSLT extension has been removed. To apply an XSL transformation to an XML document, you must use DomDocument (from DOM) and XsltProcessor (from XSL):

<?
$xml
= new DomDocument();
$xml->load('foo.xml');
                                                                               
$xsl = new DomDocument;
$xsl->load('foo.xsl');
                                                                               
$proc = new xsltprocessor();
$proc->importStyleSheet($xsl);
echo(
$proc->transformToXML($xml));
?>
up
0
ajenks at paradise dot net dot nz
10 years ago
By combining some of the user added notes and some experimentation, here's how I finally got the query string broken down and passed in as top-level parameters:

With a little more effort, this could be turned into a completely generic transform script - i.e. by adding query parms for the xml and xsl files also and excluding them from the $params array (though this lat bit may not be necessary).

Thanks to all those other users whose tips make up most of this solution!

<?php

// Process query string to $params array

$vars = explode("&", $_SERVER['QUERY_STRING']);
for (
$i=0;$i<=count($vars);$i++) {
 
$var = explode("=", $vars[$i]);
 
$params[$var[0]] = $var[1];
}

// Fire up the engine

$xslt = xslt_create();
$xml = 'test.xml';
$xsl = 'test.xsl';

$result = xslt_process($xslt, $xml, $xsl, NULL, array(), $params);
if (
$result) {
   echo
$result;
}
else {
   print
"Error:" . xslt_errno($xslt);
}

xslt_free($xslt);

?>
up
0
greg _at_ rhythmicdesign _dot_ com
10 years ago
Figuring out the syntax to get parameters in was difficult but this works for me:

// Allows user to pass argument from URL as script.php?foo=VALUE

$xml = file_get_contents ('n.xml') ;
$xsl = file_get_contents ('n.xsl') ;

 // Perform the transformation
$args = array (
        '/_xml'    =>    $xml,
        '/_xsl'    =>    $xsl
);
$params = array (
        'foo'    =>    $foo
) ;

 $html = xslt_process($xsltproc, 'arg:/_xml', 'arg:/_xsl', NULL, $args, $params);

then in the XSL FILE:
--------------------------
<xsl:param name="foo"/>

<xsl:template match="/">
    <root>
    <test><xsl:value-of select="$foo"/></test>
    <xsl:apply-templates/></root>

</xsl:template>

Note: the param definition and the '$' dollar sign
up
0
ohlesbeauxjours at yahoo dot fr
10 years ago
Thanks, Martin !

As a matter of fact, your way of doing is probably more logical than mine :)
The point is that scheme handler strangely adds a slash to your URI , if it doesn't start by any slash.

So if you call : document('http:www.url.com',page/@url)
...then $rest gets /www.url.com

But if you call : document('http://www.url.com',page/@url)
...then $rest gets //www.url.com

Another approach could consist in enclosing the scheme "http" in the XML attribute : <page url="http://www.w3.org/TR/REC-xml">
and simply doing a : $file = fopen("http:".$rest,"r");

It all depends on the context...

See also :
http://archive.gingerall.cz/archives/public/sablot2003/msg00598.html
up
0
martin_a_thomas at yahoo dot com
10 years ago
I had a little trouble making the http scheme handler work until I removed the line with the strip function and then changed the fopen
from 'http://' to 'http:' -

$file = fopen("http:".$rest,"r");

Regards // Martin
up
0
ohlesbeauxjours at yahoo dot fr
11 years ago
The XSLT document() function can only open local files.
But thanks to the Sablotron handlers, you can easely write an http-handler (or even ftp- !!).

This sample opens a particular XHTML page on the W3C, and will parse it to get the TITLE tag content.
The interesting point, here, is that the url to open (www.w3.org/TR/REC-xml) is defined... inside an XML  document :)

// XML content :
$xml='<?xml version="1.0"?>
    <page url="www.w3.org/TR/REC-xml">W3C Recommendation page</page>';

// XSL content :
$xsl='<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="ISO-8859-1" indent="no" omit-xml-declaration="yes" standalone="yes" media-type="text/html"/>
<xsl:template match="/">
    The title is : <xsl:value-of select="document(concat(\'http:\',page/@url))/html/head/title"/>
</xsl:template>
</xsl:stylesheet>';

// TRANSFORMATION :
function handGetAll($processor,$scheme,$rest) {
 $rest=substr($rest,1);
 switch($scheme) {
        case 'http':
            $file = fopen("http://".$rest,"r");
            while(!feof($file))
                $c .= fgets($file, 1024);
            fclose($file);
            return $c;
            break;
    }
}

$xh = xslt_create();
xslt_set_scheme_handlers($xh,array("get_all" => "handGetAll"));
echo xslt_process($xh,'arg:/_xml', 'arg:/_xsl',NULL,array("/_xml"=>$xml,"/_xsl"=>$xsl));
xslt_free($xh);
up
0
twa at carlbro dot dk
11 years ago
Hi... I'm back with the result :)

After a good discussion on the official Sablotron / PHP mailing list I found out how to fix the problem I had with PHP 4.3.0. So now I will just summarize it here. The full discussion can be found online on this address:
http://archive.gingerall.cz/archives/public/sab-php/msg00252.html

The problem is actually an error in my code (huh? I thought I wrote error-free code). In my XSLT file I use the document() method provided by Sablotron. In my previous example I use this syntax:
  document('foobar')
The real syntax is actually:
  document('arg:/foobar')
The reason why this worked in previous versions of PHP was due to an error in the Sablotron lib (anyway so I think).

Another thing that I would like to share is the syntax of the 2nd, 3rd and 5th argument in the xslt_process() method. In the official examples on this page the names "_xml" and "_xsl" is used. But according to the Sablotron people any name can be used. And if you are wondering if you need the preceding "/" or not - then Lenar Lhmus from the sab-php mailing list told me it would be wise to use it. Normally it works either way, but it is always the best thing to use the slash. For the full discussion on this subject see the other thread at:
http://archive.gingerall.cz/archives/public/sab-php/msg00260.html

/watson
up
0
twa at carlbro dot dk
11 years ago
It seems to be undocumented how to get the XSL parser to use two XML files at the same time to produce the output. It is possible though. Here is how it's done with the XML data in a variable:

First you need to change the 5th argument.
$xh = xslt_create();
$args = array('/_xml'=>$xml1, '/_xsl'=>$xsl, 'xml2'=>$xml2);
$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $args);

Inside the XSLT document you then need to do this:
<xsl:template match="/">
  <root>
    <foo>
      <xsl:value-of select="/foo" />
    </foo>
    <bar>
      <xsl:value-of select="document('xml2')/bar" />
    </bar>
  </root>
</xsl:template>

This creates a XML result containing a root node called "root" containing two nodes. One called "foo" with the content of the root node in $xml1 and one called "bar" with the content of the root node in $xml2.

In the $args array I don't know if it is best to write "'xml2'=>$xml2" or "'/xml2'=>$xml2". Both work. I think it has something to do with the level of the argument (/level1/level2/level3). Maybe this site reveals the true syntax:
http://www.gingerall.com/charlie/ga/act/gadoc.act?pg=sablot#i__1029

I don't know if there is another - more elegant way - to do this. But I can't find any documentation on it.

For the moment I can't get this to work in PHP 4.3.0/Windows because there seems to be a problem with the Sablotron that is shipped with this version (I have not tried the UNIX version though). I think a new version of the sablot.dll will fix this problem. But for the moment I can't seem to get PHP to work with this new version. If anyone knows how to do this then please send me a mail. I'll post anything that I find out.

/watson
up
0
geiryork at start dot no
11 years ago
An important detail if you want to use the last argument to include parameters to the template:
<?PHP
xslt_process
($xslt, 'foo.xml', 'foo.xslt', NULL, array(), array('foo' => 'FOO'));
?>

In the xsl file:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="foo"/>
<xsl:template match="/">
<xsl:value-of select="foo"/>
.........

Note the <xsl:param name="foo"/> is specified *outside* the template tag, but can be referenced inside it.
up
0
sanj at wiredesign dot com
11 years ago
Okay, now this is a neat function once you play around with it
bit...we're basically using it in two ways...one to preview data
from a mysql database, and the other to actually publish the
output to a .htm file. The following example shows us grabbing
data from the database and then using the xslt_process() function
 to combine this data file a .xsl file residing on the server...

<?php
include("../../includes/connect_to_db.inc");

$query = mysql_query("select * from mytbl where mytbl_id=1");

$mydata = mysql_fetch_array($query);

$xmlString  = '<?xml version="1.0"?><data>';
$xmlString .= '<mytbl_id>'.$mydata["mytbl_id"].'</mytbl_id>';
$xmlString .= "<mytbl_title>".$mydata["mytbl_title"]."</mytbl_title>";
$xmlString .= "<mytbl_filename>".
                    
$mydata["mytbl_filename"]."</mytbl_filename>";
$xmlString .= "</data>";

//create instance of xslt parser
$xh = xslt_create();

//store xmlString in an array using a key '/_xml'
$arguments = array('/_xml' => $xmlString);

//to write data to a file
xslt_process($xh, 'arg:/_xml', 'style.xsl', 'result.htm', $arguments);

//to view in brower
echo(xslt_process($xh, 'arg:/_xml', 'style.xsl', NULL, $arguments));

?>

The above function works well, although you can't seem to view
 the resulting htm document in the browser and write to a file at
 the same time...instead you have to call the function twice, once
 to write data to a file and once to display data in a browser.

-----------------------
here's a simple style.xsl file that works with this example...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <html>
    <head>
    </head>
    <body>
    <h1>Here's my data!</h1>
    <xsl:value-of select="data/mytbl_title" /><br />
    <xsl:value-of select="data/mytbl_filename" /><br />
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

enjoy!

Sanj Maghera
up
0
tom at hubalek dot net
11 years ago
Hi,

keep in mind that fifth parameter of function xsl_process() is __arguments__ and sixth is __xsl parameters__. I spent a lot of time learning difference between arguments and parameters ;-)

Tom
up
0
jordigasulla at yahoo dot com
11 years ago
The output of the XSLT process doesn't have to be necessarily HTML. If you receive a lot of data in the XML and want to distribute it along all your page, you can convert all your page to XHTML or force the output to be PHP code and then eval()uated. For instance, your XSL document (part of it) could look like:

<xsl:text disable-output-escaping="yes">$networth=</xsl:text><xsl:value-of select="networth" /><xsl:text disable-output-escaping="yes">;</xsl:text>

and your PHP code could look like:

$result = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
if ($result) {
  eval(addslashes($result));

that way, you can use the variable $networth in wherever you want inside your PHP file, like:

<? print $networth; ?>
up
0
dragan at iskrassoderwas dot de
11 years ago
Your input into xslt-process can of course be of external-php-script-nature. This way, you can use PHP scripts that output XML code to make up the transformation:

// Transforming "Dynamic XML" through static XSL
<?php
// Gonna contain PHP-XML output
$arguments = array(
    
'/_xml' => $xml,
);

$xh = xslt_create();

// Read plain PHP-XML output
$xmlData = fopen ("http://somehost/xmloutputtingscript.php", "r");

// Stack up output into one String
while ($line = fgets ($xmlData))
 
$xml .= $line;

// Process the document
$result = xslt_process($xh, 'arg:/_xml', 'mystylesheet.xsl', NULL, $arguments);

// Print out your transformed document
echo $result;

xslt_free($xh);
up
0
j dot metzger at steptown dot com
11 years ago
This in example on using variables from php in xsl-stylesheets (Sablotron 0.95)

with:

<xsl:param name="foo" />

and how to pass the param from php to Sablotron
(I'm using Sablotron 0.95)

The php-wrapper to Sablotron has changed somewhat in 4.0.6, so I'm using the new (experimental) syntax.

Maybe this could change again in the future

I use 4.2.1 which is compiled with:
'./configure' '--with-mysql' '--with-apxs' '--enable-xslt' '--with-xslt-sablot=/usr/local/lib' '--with-expat-dir=/usr' '--with-dom' '--with-zlib-dir=/usr'

When you want to use a param passed to the xslt_process you have to put it in the top level of the xslt-script, otherwice it won't work (means: before defining any template)
Afterwards you can use the passed param with

<xsl:value-of select="$yourparamname" />

in the template.

example:

====> xsl-stylesheet <====

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html" version="1.0" encoding="UTF-8" indent="no" omit-xml-declaration="yes" doctype-public="-//W3C/DTD XHTML 1.0 Transitional//EN" doctype-system="
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" standalone="yes" media-type="text/html" />

<xsl:param name="tpsession" />

<xsl:template match="/root/output">
   this is the template stuff. and this is the param

<xsl:value-of select="$tpsession" />

</xsl:template>

</xsl:stylesheet>

====> end of xsl - stylesheet <====

o.k. -> to call the xslt_parser (Sablotron 0.95 in my case) with params do this:

<?php

/* php script */

$xh = xslt_create();
$arg = array(    '/_xml'   =>$t_xmlString,
                     
'/_xsl'    => $t_xslString );
$param = array('tpsession' = session_name()."=".session_id());
      
$result = @xslt_process($xh, 'arg:/_xml', 'arg:/_xsl',NULL,$arg,$param);
if(!
$result){
print
xslt_error($xh);
}
else
print
$result;
xslt_free($xh);

/* end of php-script */

?>

That's it -> have fun
up
0
tkearns at fastmail dot fm
11 years ago
For those of you wondering what the hell is up with the very strange format for refering to in-memory data, see
http://www.gingerall.com/charlie/ga/act/gadoc.act?pg=sablot#i__1029

normally you pass a file name (or URI) using the 'file:' syntax. The 'arg:' syntax introduced by sablotron does not refer to a file system path, it refers to an ARGument - and of course, arguments are in-memory. In the case of PHP, the argument reference is an index to the array in parameter 5 of the xslt_process() function. I think the forward slash is just to maintain the convention of path notation.

Someone with more knowledge on the topic could probably provide a more concise definition. If so, it would be nice to have it included as part of the standard documentation set.

Some wrapper functions would make things easier still.

Here's a wrapper I wrote.

function XtDataWithFile($xmlData, $uriXSLT) {
    $args = array ( '/_xml' => $xmlData );
    $xp = xslt_create();
    $out = xslt_process($xp, 'arg:/_xml', $uriXSLT, NULL, $args);
    xslt_free($xp);
    return $out;
}

of course you could do XtFileWithData() can XtDataWithData()
up
0
msopacua at idg dot nl
11 years ago
Took me a while to figure this one out, but no matter what your stylesheet encoding and xml encoding says - argument values, need to be UTF-8.

Version 4.2.1 and sablot 0.90.
up
0
tim at zero-interactive dot com
11 years ago
[Editors note: this is basic URI syntax. Any URI, is specified as: <protocol>:location. Any resource, that can point to a network, needs '//' to indicate it's "network awareness". F.E.: ftp://, http:// and yes - file://.]

For those of you wanting to know how to fix the annoying bug telling you that an econding type of '' is unacceptable ....

Win2K, PHP 4.2.0

When processing files, you need to prefix each filename with "file://" or else you will get the above mentioned error.  Then you just need to set the encoding in your xslt file to get it to work.

You must use this prefix with your xml, xsl and output files if you are using all three like I am.

Happy hunting!!!
up
0
patrice dot lazareff at lbb dot fr dot invalid
12 years ago
This function's syntax has changed since PHP 4.0.x, here is a quick workaround for those who use a same script with various versions.
Note that in order to work with PHP 4.0.x, the commented part must not be directly within the code (or a parse error will occur).
This is why I commented it out here and call this bit of code via an include.

// PHP 4.0.6/4.1.x difference
$minor = explode(".",phpversion());
if($minor[1] >= 1) // PHP 4.1.x -- preferred
{
    include("php412_XSLT.php");

/* here is the included code
$arguments = array(
'/_xml' => $final_xml,
'/_xsl' => $xsl_content
);

$html_out = xslt_process($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);

end of included code */

} else // PHP 4.0.6 -- works okay
    xslt_process($xsl_content, $final_xml,$html_out);

echo $html_out;
up
0
theseer at php dot net
12 years ago
Note that this extension changed quite heavily in the latest releases. The documentation and howtos on the web may not match your version of php !

To verify your extension, check the configure information

 ( <?php phpinfo(); ?> )

 for either

      --with-sablot  ( old )
 or
    --enable-xslt --with-xslt-sablot (new).

Most ( all?) web documents i found describe the use of the old extension, which also changed in the process of development.

This extension is marked experimental for a reason ;)
up
0
lennart at rsd-online dot dk
12 years ago
Relative paths using xsl:include

i addition to francis's note above you can set the base path with the xslt_set_base function like this on windows like this.

xslt_set_base('file://c:/path to xslt files/')

from you xsl file use the
<xsl:include href="file.xls">

If you wish to have full access to all files in you site only specify the root path and then use
<xsl:include href="somepath/file.xls">

God speed.
up
0
francisf at videotron dot ca
12 years ago
Just because that I have look around and see other look around without any solution, so for prosperity, I give somethings that surely a lot of people know but a lot don't too.

OK, if you want to do xsl:include in your xsl file that will be parsed by your php page with xslt and sablot installed,

you have to put that in your xsl page (on a linux machine):
<xsl:include  href="file:///pathtomyxslfile/xy.xsl">

yes you do have 3 "///", the 2 first are used by sablotron and the third one is used for your path as: /pathtomyxslfile/xy.xsl

It was in the sablotron doc, well part of it.

Tested on:
php 4.1.0
Apache/1.3.22
sablot 0.80

Thanks you and take care.
up
0
chris_coupal at hotmail dot com
12 years ago
If you are getting the data from a database and creating the XML data stream for transformation, you can add the parameters for the stylesheet into the XML data. Once in the data, you can reference them from the XSL stylesheet directly.
up
0
ascii_NO_SPAM_ at _NO_SPAM_microcore dot dk
12 years ago
I noticed a slight difference in html output when upgrading to php4.1.1 on Windows.

I found the garbled output to be caused by [indent="yes"] in <xsl:output /> and simply changed it to [indent="no"].
up
0
Bill Humphries <whump at mac dot com>
12 years ago
It appears that the xslt_process function does not like to have NULLs passed into it for the Argument and Parameter arrays. However, you can pass it an empty Argument array (modulo any typos):

$xh = xslt_create();
$args = array();
$params = array( 'foo' => 'bar' );
$result = xslt_process($xh,
'source.xml','source.xsl',NULL,
$args,$params);
if ($result)
{
 print $result;
} else {
 print "Error: ".xslt_error($xh);
}

That way you don't have to worry about providing methods for reading files into the argument array.
To Top