7

我们目前使用内置 php XSL 处理器作为我们 Web 应用程序的模板引擎。这又使用 libxslt 库。它的速度似乎并不令人满意。是否有可以与 PHP 一起使用的更快/更好的 XSL 处理引擎?或者有没有办法加快 libxslt 的安装速度?

4

3 回答 3

2

我在性能方面遇到了同样的问题。当我在 Windows 下运行时,我编写了一个类,它是我通过 COM 访问的 msxml 的包装器。这比原生 PHP XSL 转换要快得多。(当然,如果您没有运行 Windows,这对您毫无帮助。)

我将在这里包含我的一些代码,通常需要注意的是我不是 PHP 专家,我不承诺它是完美的:

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();
}
于 2013-02-11T23:00:49.547 回答
0

使用对 XSLT 的原生 PHP 支持,它的内存使用率很低。这确实为 DOMDocument 和 XSLTProcessor 类创建了一个依赖项,这些类可以在 PHP 5 的 XSL.dll 中找到。

于 2013-01-08T03:47:39.060 回答
0

是的,PHP 使用libxml2 的 Libxslt,它非常流行,也许是最安全和更快的(!)XSLT 处理器,用于 15 年的XSLT1 标准。所以,这是最好的解决方案……在 XSLT 社区正在迁移到 XSLT2(非常复杂且比 v1 慢)的情况下,因为使用 2014 年的服务器机器,性能问题消失了。


提高 XSLT1 的性能

有许多方法可以改进处理,从 XML-get 到 XSLT-processed-cache。

  1. 您正在使用“大 XML 文件”吗?为什么?今天,您可以使用 PostgreSQL在 SQL 数据库中拆分记录 ,并仅检索(使用 SQL 和/或 XPath)您必须使用的片段。

  2. 重用(XSLT 和 XML)DOM 转换的对象:参见ex. 与 DOMDocument 链接的方法

  3. 检查并简化您的 XSLT:就像在任何 MVC 上下文中一样,MVC-View 不能用作“图灵完备算法”,而只能用作占位符和循环解析器(参见T. Parr 20042008)。所以进行基准测试,将性能与更简单的进行比较。
    重要提示:好的,如果您在模板中需要“辅助方法”和其他快速(如修剪!)或复杂函数,不要尝试将 XSLT1 用作 XSLT2(!),XSLT1 不适合它......相反,使用 registerPHPFunctions 作为在本教程中显示

  4. 缓存:获得性能的最后机会...如果多次使用, 您可以缓存您的 XSLT ,请参阅这个关于 XSLT-caching in PHP 的好答案,以及这个其他选项


Libxml2处理 XSLT1的Libxslt 的替代方案?我不建议浪费时间。但是,如果您真的需要复杂的模板,而不是浪费时间使用 XSLT1,那么请使用 XSLT2!

使用 PHP 的解决方案:嗯……是问题所在,请参阅此处的讨论,其中出现了一个可能的解决方案,即Saxon/C,它是唯一一款免费且良好的 XSLT2 处理器,它不是 Java,并且有一个 PHP 端口……但是是测试版(v0.3.1)。

于 2014-06-30T17:07:09.910 回答