7

現在、ビルドインphpXSLプロセッサを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 サポートを使用すると、メモリ使用量が少なくなります。これにより、PHP 5 の XSL.dll にある DOMDocument および XSLTProcessor クラスの依存関係が作成されます。

于 2013-01-08T03:47:39.060 に答える
0

はい、PHPは libxml2 の Libxslt を使用します。これは非常に人気があり、おそらく最も安全で高速な (!) XSLT-processorであり、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 2004および2008を参照)。ベンチマークなので、パフォーマンスを単純なものと比較してください。
    重要: テンプレートに「ヘルパー メソッド」やその他の高速な関数 ( trim !) や複雑な関数が必要な場合は、XSLT1 を XSLT2 (!) として使用しないでください。XSLT1 は適していません... 代わりに、registerPHPFunctions をこのチュートリアルで示しました

  4. キャッシュ: パフォーマンスを向上させる最後の機会...複数回使用する場合は 、XSLT をキャッシュできます。PHPでの XSLT キャッシングに関するこの良い回答と、この他のオプションを参照してください。


XSLT1を処理するLibxml2のLibxsltの代替?時間を無駄にすることはお勧めしません。しかし、本当に複雑なテンプレートが必要な場合は、XSLT1 で時間を無駄にするのではなく、XSLT2 を使用してください。

PHP による解決: うーん... が問題です。ここでの議論を参照してください。可能な解決策として、Saxon/Cが登場しました。これは、Java ではなく、PHP ポートを備えた唯一の無料で優れた XSLT2 プロセッサです... しかし、ベータ版 (v0.3.1) です。

于 2014-06-30T17:07:09.910 に答える