PHP -读取和修复大的无效XML文件


PHP - Read and repair big invalid XML files

我必须读取一些相当重的XML文件(在200 MB到1 GB之间),其中一些是无效的。让我给你一个小例子:

<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
  <item>
    <title>Some article</title>
    <g:material><ul><li>50 % Coton</li><li>50% Lyocell</li></g:material>
  </item>
</rss>

显然,在g:material标记中缺少了一个</ul>结束标记。此外,开发该饲料的人应该将g:material内容封闭在CDATA中,但他们没有。基本上,这就是我想做的:添加这个缺失的CDATA部分。

我试图使用SAX解析器读取此文件,但由于</ul>标记缺失,因此在读取</g:material>标记时失败。我尝试过使用XMLReader,但基本上遇到了同样的问题。我也许可以用DomDocument::loadHtml做一些事情,但是这个文件的大小与DOM方法并不真正兼容。你有任何想法,我可以简单地修复这个feed,而不必购买大量的RAM为DomDocument工作吗?谢谢。

如果文件太大,不能使用Tidy扩展名,可以使用Tidy CLI工具使文件可解析。

$ tidy -output my.clean.xml my.xml

之后,XML文件格式良好,因此可以使用XMLReader解析它们。由于tidy添加了'missing' (X)HTML部分,因此原始文档的代码位于元素内部。

(复制自https://stackoverflow.com/a/17903058/287948)

总结为两步:

  1. 使用Tidy将"free HTML"转换为"good XHTML"
  2. 使用XML Parser通过SAX API将XHTML解析为XML。

首先使用Tidy(!),将"自由HTML"转换为XHTML(或者当您不相信您的"假定XHTML"时)。参见清洁修复方法。它需要更多的时间,但运行大文件(!)…如果太大,设置几分钟作为最大执行时间。

另一个选项(用于处理大文件)是在检查或转换为XHTML后缓存XHTML文件。参见Tidy的repairfile方法。

对于"可信XHTML",使用SAX…如何在PHP中使用SAX ?

使用SAX标准API解析XML,该API在PHP中由LibXML实现(参见xmlsoft.org上的LibXML2),其接口是PHP的XML解析器,接近SAX标准API

另一种使用"LibXML2的SAX"的方法是使用另一个接口(用PHP迭代器代替传统的SAX接口),即使用XMLReader。请参阅"XMLReader使用SAX"的解释。

是的,术语"SAX"或"SAX API"没有在PHP手册中表示(!)。