PHP: XSLT f�ggv�nyek - Manual
PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links 
search for in the  
previousxmlrpc_set_typexslt_createnext
Last updated: Fri, 30 Aug 2002
view the printer friendly version or the printer friendly version with notes or change language to English | Brazilian Portuguese | Chinese | Czech | Dutch | Finnish | French | German | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Swedish | Turkish

CVII. XSLT f�ggv�nyek

Bevezet�s

Ez a PHP kiterjeszt�s a haszn�lt motort�l f�ggetlen API (programoz�si fel�letet) biztos�t XSLT transzform�ci�k elv�gz�hez, �m jelenleg csak a Ginger Alliance Sablotron motorj�t t�mogatja. M�s XSLT k�nyvt�rak t�mogat�sa is tervbe van v�ve, mint p�ld�ul Xalan vagy libxslt.

Az XSLT (Extensible Stylesheet Language (XSL) Transformations) XML dokumentumok m�s szerkezet� XML dokumentumokk� alak�t�s�t v�gz� nyelv. A World Wide Web consortium (W3C) igazgatja ezt a szabv�nyt. Az XSLT-r�l �s a kapcsolod� technol�gi�kr�l a c�men tal�lsz t�bb olvasnival�t.

Megjegyz�s: Ez a kiterjeszt�s k�l�nb�zik a PHP 4.1.x el�tti verzi�kban meglev�t�l, �s az �j kiterjeszt�s csak a PHP 4.1.x verzi�iban haszn�lhat�. A r�gi kiterjeszt�ssel kapcsolatos k�rd�seket a [email protected] levelez� list�n teheted fel.

K�vetelm�nyek

Ez a kiterjeszt�s a Sablotron �s expat csomagokat haszn�lja, amelyeknek forr�sai �s ford�tott v�ltozata is megtal�lhat�k a c�men.

Telep�t�s

UNIX rendszeren a configure szkriptet az --enable-xslt --with-xslt-sablot kapcsol�kkal kell futtatni. A Sablotron csomagot el�z�leg olyan helyre kell telep�teni, ahol a ford�t� megtal�lja.

Tartalom
xslt_create -- �j XSLT feldolgoz� ind�t�sa
xslt_errno -- visszaadja a hibak�dot
xslt_error -- visszaadja a hiba�zenetet
xslt_free -- megsz�nteti az XSLT feldolgoz� er�forr�s
xslt_process -- v�grehajtja az XSLT transzform�ci�t
xslt_set_base -- be�ll�tja az alap URI-t mindegyik XSLT feldolgoz�shoz
xslt_set_encoding -- be�ll�tja az XML dokumentumok k�dol�s�t
xslt_set_error_handler -- be�ll�tja az XSLT feldolgoz� hibakezel�j�t
xslt_set_log -- be�ll�tja a napl�f�jl nev�t
xslt_set_sax_handler -- be�ll�tja az XSLT feldolgoz� SAX kezel�j�t
xslt_set_sax_handlers --  be�ll�tja az XML dokumentumok feldolgoz�sakor megh�vand� SAX kezel�t
xslt_set_scheme_handler -- be�ll�tja az XSLT feldolgoz� scheme kezel�j�t
xslt_set_scheme_handlers --  be�ll�tja az XSLT feldolgoz� scheme kezel�it
User Contributed Notes
XSLT f�ggv�nyek
add a note about notes
[email protected]
16-Feb-2001 01:25

I did that and I still had problems. I had to manually make the xmltok shared object cose expat wouldn't build it normally.

About the phpbuilder article, the function calls are now different from the ones in the article (see above for latest).

[email protected]
26-Feb-2001 06:59

OK, I'm including this info because several people have mailed me directly to request it. It should me mentioned that in the end, I had someone else end up building PHP for me. This is their explanation of what they had to do (<hack>). No guarentees it's safe okay!?!

<hack>
in expat top level directory is a directory called lib i think it was..
in that dir (after it is compileD) will be the sources for libexpat.so.xxx etc.
you may find libexpat is the conglomeration of all the code from all of the .c
files.. if this is the case you may get away with sym linking libexpat to
libxmlparse which is the library it is going to complain about after fixing
xmltok..

xmltok i believe only requires the code from xmltok.c this is compiled (after
compilation of the package) to a corresponding .o file.. ie xmltok.o
a shared object is a dynamically linked library of functions.. a library is
comprised of one or more object files (the .o files made from the compilation of
the .c files) therefore you can create libxmltok.so from the one object file (i
think it just needed the one..) xmltok.o with the followign command as example..

ld -shared -o libxmltok.so xmltok.o

obviously from the directory with the .c and .o files in it..
(../expat.xx.xx/lib/) then you need to co[py this to somewghere that the dynamic
linker can find it at run time.. alt ernatively set your LD_LIBRARY_PATH
environment variable.. i suggest the former as it will be running in an odd
environment from apache.. copy libxmltok.so to /usr/local/lib/ for example..

libxmlparse.so can be created in a similar way... however this requires more .o
files to be added to it.. i believe it was all of them.. :/ which is odd.. means
you can probably symlink libexpat.xx.xx to libxmlparse.so and will probably
work.. try this first.. failing that..

ld -shared -o libxmlparse.so *.o

i think it was all .o think there were total of three in that dir... .

now test it extensively before using in production.. there could be issues with
the above.. test test test ...
</hack>

[email protected]
26-Feb-2001 07:25

Apparently the xmltok library conflicts have been resolved in sablot .51, the latest expat (not all that new), and PHP from CVS, available from snaps.php.net.

Here is how I installed:

1. compile sablot .51: ./configure, make, make install.

2. compile expat: ./configure, make, make install

3. both expat and sablot get put into /usr/local/lib via make install (the RPMS of these packages do not both get installed into /usr/local/lib). update your ld.so.conf file to include /usr/local/lib. then run ldconfig.

5. configure php (from snaps.php.net) with --with-expat=/usr/local/lib --with-sablot=/usr/local/lib. this should now _finally_ reward you with a libphp4.so after running make.

[email protected]
29-Mar-2001 06:49

a very useful function of the sablotron extension that is not documented here is "xslt_set_error_handler($function)" which is essential for debugging your stylesheets.<br/>
the function you pass to it goes something like "handle_xslt_error( $errno, $level, $fields )". the interesting data is in the $fields array.

[email protected]
29-Mar-2001 08:55

After having installed Sablot 0.51, expat 1.95.1 and libxml2-2.3.5 (in non standard locations), I had to manually edit config_vars.mk in topsrcdir and change -lxml to -lxml2 under EXTRA_LIBS.

Now it works perfectly. (System is Debian 2.2 without libxml1 or libxml-dev installed)

Did configure with:

--with-dom=/usr/local/libxml \
--with-sablot=/usr/local/sablotron \
--with-expat=/usr/local/expat

[email protected]
29-Mar-2001 09:05

forgot to add: you could have to change it in:

Zend/Makefile
Zend/libZend.la
libphp4.la

too, depending on what you are building (module or interpreter).

[email protected]
03-Apr-2001 04:55

For getting Sablotron to work on Windows and for a few examples to get you started, you might like to take a look at the following:



Hope this helps,
<Shanx/>

07-Apr-2001 04:14
Interesting PHP/Sablotron article:


[email protected]
27-Apr-2001 04:31

COMPILING AND INSTALLING SABLOTRON AND EXPAT FOR PHP ON A FREEBSD iServer

0) Prepare your virtual server environment. Telnet to your iserver and type:
mkdir -p ~/usr/local/apache/1.3/bin
ln /usr/bin/make ~/usr/bin/make
ln /usr/local/apache/1.3/bin/apxs ~/usr/local/apache/1.3/bin/apxs
ln /usr/local/apache/1.3/bin/httpd ~/usr/local/apache/1.3/bin/httpd

1) download the following files:
expat-1.95.tar.gz -
Sablot-0.52.tar.gz -
php4-latest.tar.gz -

2) copy these files to ~/usr/local

3) expand all these files uing tar -xvzf

4) go into expat directory and type:
./configure --prefix=/usr/home/your_iserver_login_name/usr/local
make
make install

the files will be installed under ~/usr/local/lib and ~/usr/local/include

5) set the following environment variables:
setenv LD_LIBRARY_PATH /usr/home/your_iserver_login_name/usr/local/lib
setenv LD_RUN_PATH /usr/home/your_iserver_login_name/usr/local/
setenv CPLUS_INCLUDE_PATH /usr/home/your_iserver_login_name/usr/local/include
setenv LIBRARY_PATH /usr/home/your_iserver_login_name/usr/local/lib

6) go into the Sablotron directory and type:
./configure --prefix=/usr/home/your_iserver_login_name/usr/local
make
make install

7) go into the php directory and type:
./configure --with-apxs=/usr/local/apache/1.3/bin/apxs \
--disable-debug \
--enable-trans-sid \
--enable-versioning \
--enable-ftp \
--with-mysql=/usr/home/your_iserver_login_name/usr/local/mysql \
--with-xml \
--enable-magic-quotes \
--enable-track-vars \
--enable-sablot-errors-descriptive \
--with-sablot=/usr/home/your_iserver_login_name/usr/local \
--with-expat=/usr/home/your_iserver_login_name/usr/local

then

make
and
make install

the final command - make install - should give an error about not being able to install pear.
This is normal, as pear tries to copy itself outside of your virtual server space. Since pear
is not an essential part of PHP - you can ignore this. (maybe there is a command for ./configure
in php that allows us to specify the directory in which pear will be installed?

8) final steps:
go to ~/usr/local/etc/httpd/conf
edit httpd.conf
comment out the LoadModule directive for the previous php .so module.
not that you should see the new module you just compile already inserted in the httpd.conf as
the last line of all LoadModule directives. (it should be called libphp4.so

now just go back to the command prompt after you have edited httpd.conf and type:
restart_apache

now go to your httpd document root (usually htdocs), and create a php file with the following
code in it:

<?php
phpinfo();
?>

load the file in your browser, and you should see that everything has been installed properly :)

[email protected]
13-Jun-2001 06:43

I extended the example of shanks (very helpful for me tnx), so you can call php inside your xslt file, I had the problem to pass url-parameters and did not understand how to solve it, so I use php.

<code>
<?php

/**
*
* A class to transform XML through XSLT using PHP4 Sablotron extension
*
*/

#######################################################################
## file extended by Daniel Unterberger ([email protected])
## changes: some php:eval's added

class xsltTransform
{

var $xsl_file;
var $xml_file;
var $fileName;

/**
* Constructor to the xsl_transform ticket
*
* @param $xsl_file The XSLT file containing the transformation info
* @param $xml_file The XML file containing the actual data
* @see readFile()
*/
function xsltTransform($xsl_file = '', $xml_file = '')
{
$this->xsl_string = $this->readFile($xsl_file,'php:eval');
$this->xml_string = $this->readFile($xml_file);
}

/**
* Function to read through the file
*
* @param $fileName Which file to read?
*
*/
function readFile($fileName,$php_eval="")
{
// get contents of a file into a string
$fd = fopen( $fileName, "r" );
$content = fread( $fd, filesize( $fileName ) );
fclose( $fd );

##################################################
## extension by Daniel Unterberger ([email protected])

while ( $php_eval and ( $pos_start=strpos($content,'<php:eval>') ))
{
$pos_end=strpos($content,'</php:eval>');
$content=substr($content,0,$pos_start).
eval( substr($content,$pos_start+10,$pos_end-$pos_start-10) ).
substr($content,$pos_end+11);
}

if ($GLOBALS["debug"]=="ON") print "<xmp>$content</xmp>";
## see xslt-file for debuggin if you call page.php?debug=ON (remove on life-server)

###################################################
## end extension

return $content;


}

/**
* Function to apply the actual transformation
*
*/
function applyTransformation()
{
$this->result = '';
$this->msg = xslt_process($this->xsl_string, $this->xml_string, $this->result);
if(!$this->msg) print ("Transformation failed.");
return $this->result;
}


// End of class, do not remove
}



?>
</code>

in the xslt you can call it now with

...
<tag><php:eval> return $GLOBALS["filter"]; /* all php allowed */ </php:eval></tag>
...

-------------------------------
hope this gives new inspiration
(d.u)

[email protected]
13-Jun-2001 07:19

... addition to last message

sorry shanx (miss-spelled).
having a full example you must call it like in the shanx-example. Hint dont use echo inside of <php:eval> but return, because it is only string concatenation.

<code>
<?php
## require "xslt.inc.php";

$xslt = new xsltTransform("life.xsl", "life.xml");
print ($xslt->applyTransformation());

?>
</code>

[email protected]
20-Aug-2001 02:26

XSLT + SQL = BEST !!!

I've found good way to use xslt with MySQL.
Remember ! This code would not work as is, it's to illustrate technology.

1)you do : "select * from mytable"
2)then
---------------------------------------
$fld1=$result->fields[0]; // you can do "for" here :)
$fld_name1=$result->fieldname[0];// certainly fieldname function must return field name
$myxml.="<$fld_name1>$fld1</fld_name1>"
---------------------------------------
3) write your xsl stylesheet to apply selected data.
4) Apply xsl to $myxml :)

Work perfectly !!!
A lot of time saved :)

[email protected]
28-Aug-2001 01:57

[Editor's note: moved this note here where it belongs - [email protected]]

This shows how you can use the XSLT functions to add dynamic content to the result tree, i.e. how to hand over parameters to the XSL stylesheet and write to Sablotron's document buffer.

First we assign the value of the parameter to an array in PHP:
-----------------------------------------
$xslt_params["test"] = "Run-time parameter.";
-----------------------------------------

The parameter is envoced in XSL by
-----------------------------------------
<h1>Value of run-time parameter:</h1>
<b><xsl:value-of select="$test" /></b>
<hr/>
-----------------------------------------

Don't forget to define the parameter at the beginning of your stylesheet:
-----------------------------------------
<xsl:param name="test"/>
-----------------------------------------


How can we add dynamic content from a database to the XSLT output? In Sablotron, this is done using the document buffer function.

Retrieve a table's content, store it in a XML structure assigned to an array in PHP:
-----------------------------------------
$xslt_args["buffer1"] =
"
<TestBuffer>
<Message>
<Content>
This is message 1 of buffer 1.
</Content>
</Message>
<Message>
<Content>
This is message 2 of buffer 1.
</Content>
</Message>
</TestBuffer>
";
-----------------------------------------

This is how you add the buffer to the result tree in your XSL document:
-----------------------------------------
<h1>Dynamic content from document buffer 1:</h1>
<xsl:for-each select="document('arg:/buffer1')/TestBuffer/Message">
<b><xsl:value-of select="Content" /></b><br/>
</xsl:for-each>
<hr/>
-----------------------------------------


To get the whole thing running, following functions have to be executed:
-----------------------------------------
$processor = xslt_create();
xslt_run ($processor, "file://".$DOCUMENT_ROOT.$xsl_file, "file://".$DOCUMENT_ROOT.$xml_file, "arg:/_result", $xslt_params, $xslt_args);
$result = xslt_fetch_result ($processor);
echo $result;
-----------------------------------------


The complete XSL file looks like this:
-----------------------------------------
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl=" version="1.0">
<xsl:output method="html" version="1.0" standalone="yes" indent="yes" />

<!-- define parameter -->
<xsl:param name="test"/>

<xsl:template match="/">

<!-- run-time parameter -->
<h1>Value of run-time parameter:</h1>
<b><xsl:value-of select="$test" /></b>
<hr/>

<!-- dynamic content -->
<h1>Dynamic content from document buffer 1:</h1>
<xsl:for-each select="document('arg:/buffer1')/TestBuffer/Message">
<b><xsl:value-of select="Content" /></b><br/>
</xsl:for-each>
<hr/>

</xsl:template>

</xsl:stylesheet>
-----------------------------------------

[email protected]
05-Dec-2001 07:37

We have install instructions on the alt php faq site now

[email protected]
05-Dec-2001 08:23

In PHP 4.1.0 the Sablotron extension has been replaced by a more generic extension. The configure command changed:

./configure --enable-xslt --with-xslt-sablot

Look in the file php4/ext/xslt/README.XSLT-BACKENDS for more information about acutally using the extension :)

[email protected]
09-Jan-2002 08:25

I extended the example of Daniel Unterberger even more. I had the problem to evaluate PHP code within my xml data files (e.g. to output database results) and after that apply a xsl stylesheet to the generated data.

When I tried Daniel's solution I found it quite useful but noticed that you can't "print out" from your PHP Code. You're bound to annoying return()-Statements, wich makes it impossible to loop outputs or concatenate strings and then return them. If you try to do so, you will notice that a statement like
...
<php:eval>
for($i=0; $i<10; $i++)
echo "This is number ".$i;
</php:eval>
...

will result in PHP to do the output right in the moment when the eval()-Statement is run.

Things do, at least, work fine if you keep it simple:

...
<php:eval>
return("Hello World!");
</php:eval>
...

I tried to fix that and came to a solution. The following code is just a snippet from my XSLT-class. The uppercase letters are constants defined in a header file. (e.g. define('PHP_EVAL_START_TAG', '<php:eval>');

...
function xmlString() {

$fd = fopen($this->xmlFileLocation, 'r');
$xmlString = fread($fd, filesize($this->xmlFileLocation));
fclose($fd);

if($this->contentType == DYNAMIC_CONTENT) {

while(!(strpos($xmlString, PHP_EVAL_START_TAG) === false)) {

$startPos = strpos($xmlString, PHP_EVAL_START_TAG);
$endPos = strpos($xmlString, PHP_EVAL_END_TAG);

ob_start();
eval(substr($xmlString, $startPos + strlen(PHP_EVAL_START_TAG), $endPos - $startPos - strlen(PHP_EVAL_START_TAG)));
$evaluatedString = ob_get_contents();
ob_end_clean();

$xmlString =
substr($xmlString, 0, $startPos).$evaluatedString.substr($xmlString, $endPos + 11);
}
}

return($xmlString);
}
...

[email protected]

[email protected]
11-Jan-2002 09:15

The XSLT functions may experience conflicts with Apache in some configurations, causing random segfaults in httpd. Apache has included a 'lite' version of expat in their recent distributions, which can cause conflicts with expat. Apache1.3.22 solves the problem by configuring itself to use the expat you have installed, instead of the built-in. If you compiled Apache before you installed expat, make sure you upgrade and/or recompile your Apache server with the same version of expat that PHP and Sablotron are using.
[email protected]
21-Jan-2002 09:53

The extension dll in Windows is no longer php_sablot.dll, it's php_xslt.dll
[email protected]
01-Feb-2002 12:43

There is a german tutorial regarding the new xslt functions as of version 4.1.0.

There is a class that handles xslt functions (Version 4.1 and before)!


[email protected]
06-Feb-2002 07:59

For those of you who are having problems installing php with Sablotron (I was one), here's what I did.

What I'm running:
-Apache 1.3.19
-PHP 4.1.1
-Linux

This is what I did:
1. Go to the web site previosly mentioned by [email protected],

2. Click the FAQ: "How do I install Sablotron with PHP?�"

The only thing that needs to be done differently for PHP 4.1 and it's sub versions (ex. 4.1.1) is the options on the configure line.
Use --enable-xslt --with-xslt-sablot instead.

[email protected]
13-Feb-2002 01:34

As far as I can see xslt extension is being prepared to use with any other backend like libxslt. Be aware :)
[email protected]
23-May-2002 04:23

Building Sablotron on Solaris with.
gcc 3.0.3 and native linker
libtool (sunfreeware)
apache 1.3.24
php-4.2.1
sablotron-0.90
expat-1.95.2

When configuring Apache you might experience this error..

libsablot.so: undefined reference to `operator new[](unsigned)'
libsablot.so: undefined reference to `__cxa_call_unexpected'
libsablot.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
libsablot.so: undefined reference to `operator delete(void*)'
libsablot.so: undefined reference to `__gxx_personality_v0'
libsablot.so: undefined reference to `vtable for __cxxabiv1::__class_type_info'
libsablot.so: undefined reference to `operator delete[](void*)'
libsablot.so: undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info'
libsablot.so: undefined reference to `operator new(unsigned)'

To cure it make sure that during the configure stage you feed configure LDFLAGS variable like so.

LDFLAGS=' -lstdc++' ./configure

Otherwise Apache's compiler sanity check will balk.

[email protected]
30-Jun-2002 12:49

I had quite a bit of trouble working out the steps to compiling xslt with the newest versions of Apache, Sablotron, and PHP. For the benefit of others here is the general process: compile expat 1.95.2-2, install expat, compile iconv 2.0.4, install iconv, patch sablotron,
compile sablotron 0.95, install sablotron, compile apache 1.3.26,
install apache, patch php, compile php, 4.2.1, install php, configure apache.

Sablotron and PHP won't work unless you download and apply the two source patches from Sablotron's download page. PHP will make Apache throw an error unless you compile PHP with iconv support, even though it compiles without error.

I hope this helps. :)

[email protected]
02-Aug-2002 07:49

There's no need to rebuild Apache to link it against libstdc++. Just edit the PHP Makefile and add -lstdc++ to LTLIBRARY_LDFLAGS.
gherson at DatainFormation com
22-Aug-2002 03:56

Compiling xslt into cgi version of PHP4.2.2 on linux 2.4.7:
Lots of work was needed. I had to download Mozilla's js-1.5rc4-2.i386.rpm and js-devel-1.5rc4-2.i386.rpm and the Sablotron library tarball, all from . Applying patch was nec (found by searching google with "SXPF_DISPOSE_VALUES", which make blamed for failing, claiming it had a duplicate value). Export CPLUS_INCLUDE_PATH="/usr/include/js/" was nec to get past a Sablotron make or configure error "required file jsapi.h not found". Then ./configure --enable-javascript; make; make install worked w/o errors. Then, for PHP 4.2.2 compilation:
$ ./configure --with-pgsql=/usr/local/pgsql --enable-force-cgi-redirect --enable-xslt --with-xslt-sablot --with-sablot-js
followed by $ make and # make install. No errors. /usr/local/bin/php is the new cgi executable. $ php -v confirmed the version, and function phpinfo() confirmed xslt enabled. (Along the way I had tried the rpm version of Sablotron and compiling the CVS version of PHP when i got stuck, to no avail.)

[email protected]
26-Aug-2002 08:35

INSTALLING PHP XSLT ON WINDOWS

Thanks to a wonderful program which lists dependecy heirachies for windows executables (and .dll files), I was able to track down the problem. What the PHP manual neglects to tell you (it only has instructions for Unix) is that you need to find sablot.dll, I suspect that php_xslt.dll is just a stub which calls this program. Now sablot also needs libexpat.dll (which I discovered thanks to dependency walker).

so anyone who wants to do PHP XSLT under windows, not only do you need to uncomment php_xslt.dll in the php.ini file, you need to find sablot.dll and libexpat.dll and stick em in your system32 diectory.

matthias-at-mlienau.de
30-Aug-2002 12:52

For those guys who mess up with compiling the current Sablotron 0.95 sources from gingerall.com:

Here is a patch which corrects a typo.
Or - go to src/engine/domprovider.cpp and change "voiD" to "void" in line 558 and compile again...

*** domprovider.cpp.diff Thu Aug 29 23:32:59 2002
--- domprovider.cpp Thu Aug 29 23:32:14 2002
***************
*** 555,561 ****
if (external) cdelete(external);
}

! void DOMProviderUniversal::setExtProvider(DOMHandler *domh, voiD *data)
{
if (external) cdelete(external);
if (domh)
--- 555,561 ----
if (external) cdelete(external);
}

! void DOMProviderUniversal::setExtProvider(DOMHandler *domh, void *data)
{
if (external) cdelete(external);
if (domh)

add a note about notes
previousxmlrpc_set_typexslt_createnext
Last updated: Fri, 30 Aug 2002
show source | credits | stats | mirror sites
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Wed Sep 4 00:18:56 2002 CEST