我必须读取一些相当重的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)
总结为两步:
- 使用Tidy将"free HTML"转换为"good XHTML"
- 使用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手册中表示(!)。