4

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

在网络服务器上。

警告: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

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

4

1 回答 1

5

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

然而,对于 DOM,大量的内存消耗是很正常的。

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

这给我们留下了 DOM 的替代方案;有一个,称为 SimpleXML。如果您的文档有命名空间, SimpleXML 使用起来会有些棘手。一个古老的基准似乎表明它比大文件上的 DOM 更快,并且在内存消耗方面可能也更少浪费。

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

所以,这里是你的选择。选一个。

  • 使用 SAX 解析和处理 XML
  • 使用SimpleXML并希望它允许在同一内存中使用稍大的文件。
  • 执行一个外部 XSLT 处理器,并希望它允许在同一内存中使用稍大的文件。
  • 使用此方法拆分和合并 XML,并将 XSLT 仅应用于小块。此方法仅适用于某些模式。
于 2012-06-25T21:28:38.433 回答