Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster XSL processor for PHP

Tags:

php

xslt

We currently use build in php XSL processor as a templating engine for our web app. Which in turns uses libxslt library. The speed of it seems to be unsatisfactory. Is there a faster/better XSL processing engine that can be used with PHP? Or is there a way to speed up libxslt installation?

like image 604
Mike Starov Avatar asked Nov 06 '12 19:11

Mike Starov


1 Answers

I had the same problem with performance. As I'm running under Windows, I wrote a class that's a wrapper around msxml that I access via COM. This was much faster than native PHP XSL transformation. (Naturally, this wont help you at all if you're no running Windows.)

I'll include some of my code here, with the usual caveats that I'm no PHP guru and I make no promises that it's anything like perfect:

class xsltransform {
    private $xmlfilename;
    private $xslfilename;
    private $xslt;
    private $xslDoc;
    private $xmlDoc;
    private $xslProc;
    private $parameters = array();
    public function __construct() {
        $this->xslt = new COM("Msxml2.XSLTemplate.6.0");
        $this->xslDoc = new COM("Msxml2.FreeThreadedDOMDocument.6.0");
        $this->xslDoc->async = false;
        //to allow xsl:import in xsl since security changes in MSXML 6.0
        //http://msdn.microsoft.com/en-us/library/windows/desktop/ms763800(v=vs.85).aspx
        $this->xslDoc->resolveExternals = true;
        //to allow xsl:document in xsl since security changes in MSXML 6.0
        $this->xslDoc->setProperty("AllowDocumentFunction", true);
        $this->xmlDoc = new COM("Msxml2.DOMDocument.6.0");
        $this->xmlDoc->async = false;
    }
    private function loadxml() {
        $this->xmlDoc->load($this->xmlfilename);
        $this->checkParseError($this->xmlDoc, "xmlDoc, filename={$this->xmlfilename}");
    }   
    private function loadxsl() {
        $this->xslDoc->load($this->xslfilename);
        $this->checkParseError($this->xslDoc, "xslDoc, filename={$this->xslfilename}");    

    }
    private function addParameters() {
        foreach ($this->parameters as $name => $value) {
            $this->xslProc->addParameter($name, $value, '');
        }

    }                    
    public function setxmlfilename($filename) {
        $this->xmlfilename = $filename;    
    }
    public function setxslfilename($filename) {        
        $this->xslfilename = $filename;    
    }
    public function addProperty($name, $value) {
        $this->parameters[$name] = $value;
    }
    private function checkParseError($doc, $message = '') {
        if ($doc->parseError->errorCode) {
            print("XML Parse Error (" . $message . "): " . $doc->parseError->errorCode . $doc->parseError->reason);
            exit; 
        }
    }
    private function loadAndTransform() {
        $this->loadxsl();
        $this->xslt->stylesheet = $this->xslDoc;
        $this->xslProc = $this->xslt->createProcessor();
        $this->xslProc->input = $this->xmlDoc;
        $this->addParameters();
        $this->xslProc->transform();
    }
    public function output() {
        $this->loadxml();
        $this->loadAndTransform();            
        return $this->xslProc->output;
    }
    public function transform($xmlText) {
        $this->xmlDoc->loadXML($xmlText);
        $this->checkParseError($this->xmlDoc, "xmlDoc");
        $this->loadAndTransform();            
        return $this->xslProc->output;
    }
}; 



function xslTransform($xmlfilename, $xslfilename, $params) {
    $scriptPath = (dirname(__FILE__));
    $xslfilenameabsolute = "{$scriptPath}'\\..\\xsl\\{$xslfilename}";
    if (!file_exists($xmlfilename)) {
        die("{$xmlfilename} does not exists.");
    }
    if (!file_exists($xslfilenameabsolute)) {
        die("{$xslfilenameabsolute} does not exists.");
    }
    $xsltransform = new xsltransform();
    $xsltransform->setxmlfilename($xmlfilename);
    $xsltransform->setxslfilename($xslfilenameabsolute);
    foreach($params as $key=>$param) {
        $xsltransform->addProperty($key, $param, '');
    }
    return $xsltransform->output();
}
like image 164
Richard A Avatar answered Nov 07 '22 16:11

Richard A