Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define PHP-Function in XSL and calling it. Possible? How?

Like the title tells: Is it possible to write a PHP-Function in a XSL-Document and call it afterwards?

I have no case, where I wanna do that. Its just a thing it came into my mind while learning XSL.

In XSL you can compose something like:

<xsl:processing-instruction name="php">
   ...some php...
</xsl>

The PHP code will be run in your rendered page. Is it possible to create e.g. a PHP Function in the processing-instruction and call it later (in the same template)?

Pseudo-Sample:

<xsl:template>

   <xsl:processing-instruction name="php">
      ...some php processing $foo...
   </xsl>

   <xsl:variable name="foo" select="xpath/node">

   <xsl:value-of select="call-php-function-with-$foo"/>

</xsl>

I'm looking forward to your solutions/approaches :)

Chris

like image 745
ChrisBenyamin Avatar asked Oct 25 '22 10:10

ChrisBenyamin


2 Answers

I think the selected answer is pointing in the wrong direction. No need to use FXSL, you CAN easily add extensions written in other languages to XSLT - for example Jython or Javascript with Xalan, Java with most Java processors, etc.

As for PHP, if you are doing the XSLT processing in a PHP script (as opposed to, say, Xalan run from Ant or something) then it is very easy to use XSLTProcessor::registerPHPFunctions which allows you to write things like

$xsl = <<<EOF
...
<xsl:value-of select="php:function('myFunc', . )"/> 
...
EOF;

function myFunc( $node ) {
//etc

Of course, only a PHP script would then be able to process the XSL correctly.

It's all quite clearly documented at http://www.php.net/manual/en/xsltprocessor.registerphpfunctions.php

like image 176
gotofritz Avatar answered Nov 15 '22 07:11

gotofritz


It can be done (bear in mind Dimitre that if he's asking about PHP he's almost certainly limited to XSLT 1.0, and FXSL isn't quite what he's after).

Firstly, if are planning to write the PHP yourself, and use it as part of a document processing flow, it's probably a bad choice of language for this. In the case where you just want to expand the functionality of XSL a tiny bit with a few PHP functions of your own or useful library functions like preg_replace, so you can call them from your XSLT, you're absolutely fine if you know what those are beforehand: you export the PHP functions to the XSLT and just call them from there.

If the code you want to execute is different for each document though, it gets harder (ie, for processing instructions in the documents you are trying to process which contain PHP, and you want the XSLT script when evaluating your document to execute the processing instructions). Try and factor out the functions into a known set and just call them from the PHP, but if you can't and still want to try, it's down to hackery.

(I am assuming you know about PHP's way of exporting functions to XSLT: you make some ordinary PHP functions, you export them to the XSLT script using registerPHPFunctions, and them just call them as functions inside the XSLT. That's a well-trodden path; check the docs.)

Back to executing PHP code in your document's PIs from an XSLT script.

(Not done myself, but shouldn't be all that hard to implement.) It is not possible to do it in one pass, I believe. You have to call the XSLT processor, and whenever you hit the PHP you want to run, put in a marker tag (eg <phpmarker md5ofcode="php:md5(...)">) and pass the code back up to the calling PHP. Hacky, but potentially liveable-with would be to put it in an xsl:message and catch it from a custom handler in PHP.

When the first run has ended, do a bit of string manipulation to make a wrapper function around each block of code you grabbed, eval that string to create the functions, export them to XSLT engine, and then re-call with a second XSLT script which will cat the marker nodes, and call the PHP on their contents.

Ugly? Yes. You might want to explain why you would want it, but it should be possible (in two passes) to get it to work.

Edit: Having reread your question a few more times, I'm increasing confused. Are you sure you want to PIs in your XSLT? PIs go in the documents, explaining how they are to be processed. If the PHP is meant to be going in the XSLT file and that's not a typo, I think you might be a bit confused, and it's just a plain vanilla application of PHP's registerPHPFunctions. You just have to put the PHP in a separate file and call it from the XSLT, which isn't a huge burden considering XSLT scripts don't have to contain much functionality before they're big enough to split into two files.

like image 40
Nicholas Wilson Avatar answered Nov 15 '22 06:11

Nicholas Wilson