XSLTProcessor xmlSAX2Characters:内存不足

San*_*lai 4 php xml xslt xml-parsing

我有一个页面加载500 MB的xml文件,并使用xsl模板解析该文件.解析器在我的本地环境中完美运行.我正在使用WAMP.

在Web服务器上.

警告:DOMDocument :: load()[domdocument.load] :( null)xmlSAX2Characters:/home/mydomain/public_html/xslt/largeFile.xml中的内存不足,/ home/mydomain/public_html/xslt/parser_large中的行:2031052 .php在第6行

我的代码如下,第6行加载xml文件

<?php
$xslDoc = new DOMDocument();
$xslDoc->load("template.xslt");

$xmlDoc = new DOMDocument();
$xmlDoc->load("largeFile.xml");

$proc = new XSLTProcessor();
$proc->importStylesheet($xslDoc);
echo $proc->transformToXML($xmlDoc);
?>

我已经尝试将php.ini文件从wamp安装复制到上面代码所在的文件夹.但这没有帮助.此php.ini文件中的内存限制为memory_limit = 1000M

任何关于此的建议/经验将不胜感激

Jir*_*ika 5

这是一个可悲的事实.使用基于DOM的XML有两种基本方法,其中整个XML文件一次存在于内存中(具有相当大的开销以使其快速遍历),以及基于SAX的文件通过内存的位置,但仅限于它的一小部分在任何给定时间都存在.

但是,使用DOM,大量内存消耗是非常正常的.

现在,XSLT语言通常允许随时访问整个文件的任何部分的构造,因此它需要DOM样式.一些编程语言具有允许将SAX输入提供给XSLT处理器的库,但这必然意味着对XSLT语言或内存消耗的限制并不比DOM更好.但是PHP 没有办法让XSLT读取SAX输入.

这让我们有了DOM的替代品; 有一个,叫做SimpleXML.如果您的文档具有名称空间,则使用SimpleXML有点棘手. 一个古老的基准测试似乎表明它比大文件上的DOM更快,并且可能也更少浪费内存消耗.

最后,我曾使用另一种编程语言.解决方案是根据简单的规则将文档拆分为小文档.每个小文档都包含从整个文档复制的标题,一个"detail"元素和一个页脚,使其格式对大XML文件的模式有效.它是使用XSLT处理的(假设一个细节元素的处理不会查看任何其他细节元素)并且输出结合起来.这有点像魅力,但它没有在几秒钟内实现.

所以,这是你的选择.选一个.

  • 使用SAX解析和处理XML.
  • 使用SimpleXML并希望它允许在同一内存中稍大的文件.
  • 执行外部XSLT处理器并希望它允许在同一内存中稍大的文件.
  • 使用此方法拆分和合并XML,并仅在小块上应用XSLT.此方法仅适用于某些模式.