我正在使用下面的函数,但不确定它是否总是安全的.是吗?没有DOM-内存或“残余XSLT”在那里?
function XSLproc_reuse($domXsl) {
static $XSLproc=NULL;
if (!$XSLproc)
$XSLproc = new XSLTProcessor();
return $XSLproc->importStylesheet($domXsl); // STABLE?
}未来对它没有“意外副作用”?
PS:我的XSLT处理有一些奇怪的错误.因此,在这里张贴一个(许多其他的)假设,以检查是否确定或必须避免。这个在XPath中更明显,请参见另一个相关问题。
另一种方法是重用更多的处理表(我在库中使用的),也可以重用导入的XSLT:
function XSLproc_reuse2($nameOrDomXsl='', $domXsl=NULL) {
static $XSLproc=NULL;
static $name='';
if (!$XSLproc)
$XSLproc = new XSLTProcessor();
// else reune of the already initialized $XSLproc.
if (is_object($nameOrDomXsl))
return $XSLproc->importStylesheet($nameOrDomXsl); // STABLE?
elseif ($nameOrDomXsl==$name);
return $XSLproc; // imported in the last call, STABLE?
else { // recording for future reuse:
$name = $nameOrDomXsl;
return $XSLproc->importStylesheet($domXsl);
}
}发布于 2013-11-20 09:25:37
要理解这个问题,了解XSLTProcessor如何在内部存储数据以及调用XSLTProcessor::importStylesheet后发生了什么非常重要。实现该类的代码位于php源代码的\ext\xsl\xsltprocessor.c中。
这个解释必须简化一些--用纯php 'c‘编写。php对象中的内容--就с而言,函数只是在全局上下文中操作。
Web需要了解如何以及如何处理导入的数据:
DOMDocument或SimpleXMLElement的对象。docp是一个importStylesheet参数)
// php _libxml_import_node (在\ext\libxml\libxml.c中)只是通过php对象指针获取//实际的xmlNodePtr XMLlib2对象指针。nodep = php_libxml_import_node(docp TSRMLS_CC);if (nodep) { doc = nodep->doc;} if (doc == NULL) { php_error(E_WARNING,“无效文档”);RETURN_FALSE;} //Next是xmlCopyDoc的原始注释和调用,生成样式表的复制//。我回答的主要内容。/* libxslt使用_private,所以我们必须复制导入的样式表文档,否则节点代理将变得一团糟*/ newdoc = xmlCopyDoc(doc,1);.//在这里,我们使用libxslt函数创建内部样式表对象。
sheetp = xsltParseStylesheetDoc(newdoc);
..。
//之后,一些行将它们存储到//XSLTProcessor类实例的内部变量中。php_xsl_set_object(id,sheetp TSRMLS_CC);importStylesheet之后,您可以使用$stylesheet对象做任何您想做的事情--它不影响XSLTProcessor的工作,因为它使用$stylesheet的副本。但是,如果不再次调用$stylesheet,您就不能刷新或更新importStylesheet。XSLTProcessor::transformToDoc (php_xsl_apply_stylesheet -从477行相同来源)和其他transform方法是什么?它们中的每一个都分配它们的输出类型(在XSLTProcessor::transformToDoc情况下为XSLTProcessor::transformToDoc),并使用内部sheetp对象(在importStylesheet中创建)来转换数据。
在评论后编辑
transformTo时都推荐使用transformTo。如果样式表在大型样式表上使用xsl:key,则应该重用,因为需要额外的XML节点遍历。XSLproc_reuse2是有意义的,应该被使用。您可以在$stylesheet使用中缓存xsl:key复制和遍历过程。不是指针,而是所有的对象及其内部。让s some more words about how the转换文档工作:
DOMDocument对象。xsltNewTransformContext和xsltApplyStylesheetUser从libxslt制作缆车。DOMDocument在XSLTProcessor或libxslt中没有任何惩罚代码,其中XSLTProcessor重用错误。在使用xslcache 0.7.2之前,我尝试使用这个项目,并将其调优到使用out站点。这是我的经验。当时,我们使用XSLT作为模板引擎,并使用大型XSLT模板(在3~5MB的简化代码中)。在这种情况下,importStylesheet的缓存具有很大的性能提升。但是没有任何机会缓存transformToDoc结果--每次您称之为它时,libxslt使用内存中的两个已准备好的对象进行dom操作,并给出新对象作为结果。
发布于 2013-11-21 21:58:56
使用静态定义全局状态,即定义为“不稳定”。它可以从程序中的任何地方更改。使用对象可以获得一个本地状态(在对象实例中)。我也建议使用数组。这样它就可以为不同的文件存储多个处理器。
class XsltFactory {
private $_processors = array();
public function get($file) {
if (!isset($this->_processors[$file])) {
$xslDom = new DOMDocument();
$xslDom->load($file);
$xslProc = new XSLTProcessor();
$xslProc->importStylesheet($xslDom);
return $this->_processors[$file] = $xslProc;
}
return $this->_processors[$file];
}
}
$xsltFactory = new XsltFactory();
var_dump(
htmlspecialchars(
$xsltFactory->get($template)->transformToDoc($xmlDom)->saveXml()
)
);提高性能的一个更好的解决方案是xslcache。它在进程中缓存$xslt->importStyleSheet($filename)的结果。如果进程被重用,那么编译的xsl也是如此。
https://stackoverflow.com/questions/18086094
复制相似问题