XSLTProcessor xmlSAX2Characters:内存不足

时间:2012-06-25 21:03:34

标签: php xml xslt xml-parsing

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

在网络服务器上。

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

我的代码如下,第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

非常感谢任何关于此的建议/经验

1 个答案:

答案 0 :(得分:5)

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

然而,使用DOM,大量内存消耗是非常正常的。

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

这让我们有了DOM的替代品;有一个,叫做SimpleXML。如果您的文档具有名称空间,则SimpleXML有点trickyAn ancient benchmark似乎表明它比大文件上的DOM更快,并且可能也更少浪费内存消耗。

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

所以,这是您的选择。选择一个。

  • Parse and process XML using SAX
  • 使用SimpleXML并希望它允许同一内存中稍大的文件。
  • 执行外部XSLT处理器,并希望它允许在同一内存中稍大的文件。
  • 使用this method拆分和合并XML,并仅在小块上应用XSLT。这种方法仅适用于某些模式。