是否有用于 PHP 的宽松、宽松的 XML 解析器?
Posted
技术标签:
【中文标题】是否有用于 PHP 的宽松、宽松的 XML 解析器?【英文标题】:Is there a lax, permissive XML parser for PHP? 【发布时间】:2011-08-27 06:08:12 【问题描述】:我正在寻找一个解析器,它可以让我成功解析损坏的 xml,例如采用“最佳猜测”方法。
<thingy>
<description>
something <b>with</b> bogus<br>
markup not wrapped in CDATA
</description>
</thingy>
理想情况下,它将产生一个东西对象,带有描述属性和里面的任何标签汤。
欢迎提出有关如何解决问题的其他建议(除了从有效标记开始)。
非 php 解决方案(例如 Beautiful Soup (python))并没有被排除在外,但我更愿意坚持公司的主流技能
谢谢!
【问题讨论】:
您没有理解 XML 的重点:XML 的主要思想是,如果遇到语法错误,它将杀死您、您的家人、您的朋友以及您曾经与之交谈过的任何人。没有严格错误处理的 XML 不再是 XML ^^ @nikic - 我一直处于与 OP 相同的位置,即不得不处理由第三方提供的损坏的“XML”输入,这些输入没有得到 XML 的重点。虽然我同意这并不理想,但当必须导入数据并且我们无法让第三方修复他们的系统时,我们只需要处理它。 :-( 和@Spudley 描述的差不多,是的 (提示) devzone.zend.com/article/2387 如果它可以成功解析损坏的 XML,那么它可能是一个非常有用的软件,但它不是 XML 解析器(符合标准的 XML 解析器不允许这样做)。 【参考方案1】:您可以使用DOMDocument::loadhtml()
(或DOMDocument::loadhtmlfile()
)将损坏的XML 转换为正确的XML。如果您不喜欢处理 DOMDocument
对象,请使用 saveXML()
并使用 SimpleXML 加载生成的 XML 字符串。
$dom = DOMDocument::loadHTMLfile($filepath);
if (!$dom)
throw new Exception("Could not load the lax XML file");
// Now you can work with your XML file using the $dom object.
// If you'd like using SimpleXML, do the following steps.
$xml = new SimpleXML($dom->saveXML());
unset($dom);
我试过这个脚本:
<?php
$dom = new DOMDocument();
$dom->loadHTMLFile('badformatted.xml');
if (!$dom)
die('error');
$nodes = $dom->getElementsByTagName('description');
for ($i = 0; $i < $nodes->length; $i++)
echo "Node content: ".$nodes->item($i)->textContent."\n";
从 CLI 执行此操作时的输出:
carlos@marmolada:~/xml$ php test.php
Warning: DOMDocument::loadHTMLFile(): Tag thingy invalid in badformatted.xml, line: 1 in /home/carlos/xml/test.php on line 3
Warning: DOMDocument::loadHTMLFile(): Tag description invalid in badformatted.xml, line: 2 in /home/carlos/xml/test.php on line 3
Node content:
something with bogus
markup not wrapped in CDATA
carlos@marmolada:~/xml$
编辑:一些小的更正和错误处理。
edit2:更改为非静态调用以避免 E_STRICT 错误,添加测试用例。
【讨论】:
唉,两者都失败了——XML 是因为 borked XML,而 HTML 是因为“无效”(对于 HTML)元素标签。 在我现在完成的一项测试中,它会发出有关未知 html 节点的警告,但它会正确加载所有元素(包括这些“未知”标签)。 您,先生,是对的 - 尽管警告是 PITA,但我可以暂时让这些特定任务静音。 只需对特定调用使用 @ 运算符:@$dom->loadHTMLFile($file);
【参考方案2】:
另一种方法是先使用Tidy HTML 库(PHP binding here) 来清理HTML。它在相当多的相当可怕的输入中幸存下来,而且我以前见过人们用它来抓取相当复杂的 HTML。
【讨论】:
这是我的建议。预处理,一旦格式正确,您根本不需要验证它。我假设这是某人对 RSS 网络提要的想法? 某人对产品目录的想法,甚至 - 哦,卡洛斯的回答做到了,尽管我可能会按照你的建议继续整理 HTML ......只是为了确保内部标记没有其他任何东西。以上是关于是否有用于 PHP 的宽松、宽松的 XML 解析器?的主要内容,如果未能解决你的问题,请参考以下文章