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?
-
3I suffer from the same problem. The only thing I found out: If you want to transform xml files that are located on your server, replace the host name in the url of the files with "localhost". This helped me speed up things a lot. HTH, Andy – BergListe Dec 08 '12 at 16:55
-
2If you just do the transformation with PHP's XSL processor, consider using any XSLT processor with a cli interface nistead and trigger the transformation via `exec`. – Gordon Jan 05 '13 at 11:54
-
2Can you give a short example that takes 'long' to translate? How long takes it? What hw do you use? – hek2mgl Jan 08 '13 at 00:51
-
2Are you sure your XSLT stylesheets are optimized? Check your XPATHs: do not use `//` when you are not obliged to ; use relative paths whenever you can. – Aurélien Bénel Jan 27 '13 at 16:54
-
The saxon XSLT processor is very fast and has a great optimizer. Java, .NET, and in-browser javascript are available. It's not "for PHP", but then libxslt really is "for PHP" either, so it seems it could work. See http://en.wikipedia.org/wiki/Saxon_XSLT – kbulgrien Jan 15 '14 at 16:33
-
I copied the XML file I had (900MB, continually searching from) from NVMe to /dev/shm for tmpfs/memory usage. Result was about same speed. This was using xsltproc which I think uses libxslt. Nothing I can find to speed up xsltproc. Any ideas, let me know. – Roel Van de Paar Jun 06 '19 at 05:05
3 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();
}

- 25,759
- 11
- 71
- 103

- 2,783
- 2
- 22
- 34
-
Strange, [this only benchmark of 2009 comparing MSXML* with LibXSLT](http://marc.info/?l=perl-xml&m=99441054812404&w=2) says that *LibXSLT is faster* (!). The need for performance is only a file access problem? Today, 2014, persist? – Peter Krauss Dec 23 '14 at 22:27
Using native PHP support for XSLT it has low memory usage. This does create a dependency for DOMDocument and XSLTProcessor classes which can be found in the XSL.dll for PHP 5.

- 41
- 1
- 3
Yes, PHP use the Libxslt of libxml2, that is so popular and perhaps the safest and faster (!) XSLT-processor, for the 15 years old XSLT1 standandard. So, this is the best solution... In a context where the XSLT community is migrating to XSLT2 (very complex and slower than v1), because with 2014's server-machines the performance problems vanishes.
IMPROVE performance of your XSLT1
There are many ways to improve processing, ranging from XML-get to XSLT-processed-cache.
You are using "big XML files"? Why? Today you can split into records at a SQL database with PostgreSQL, and retrive (with SQL and/or XPath) only the fragments that you must use.
Reuse of (XSLT's and XML's) DOM-converted objects: see ex. method chaining with DOMDocument.
Check and simplify your XSLT: like in any MVC context, the MVC-View is not to be used as a "Turing Complete algorithm", but only a placeholder and loop resolver (see T. Parr 2004 and 2008). So benchmark, compare the performance with simpler ones.
IMPORTANT: ok, if you need "helper methods" and other fast (like trim!) or complex functions in your template, not try to use XSLT1 as XSLT2 (!), XSLT1 is not for it... Instead, use registerPHPFunctions as showed in this tutorial.Cache: the last opportunity of gain performance... You can cache your XSLT if use more than once, see this good answer about XSLT-caching in PHP, and this other option.
Alternative to Libxslt of Libxml2 processing XSLT1? I not recomend lost time with it. But, if you really need complex templates, not lost time with XSLT1, use XSLT2!
Solution with PHP: hum... is the problem, see discussion here, where a possible solution emerged, the Saxon/C, that is the only free and good XSLT2 processor that is not Java, and have a PHP port... but is beta (v0.3.1).

- 1
- 1

- 13,174
- 24
- 167
- 304