是否有用于 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-&gt;loadHTMLFile($file);【参考方案2】:

另一种方法是先使用Tidy HTML 库(PHP binding here) 来清理HTML。它在相当多的相当可怕的输入中幸存下来,而且我以前见过人们用它来抓取相当复杂的 HTML。

【讨论】:

这是我的建议。预处理,一旦格式正确,您根本不需要验证它。我假设这是某人对 RSS 网络提要的想法? 某人对产品目录的想法,甚至 - 哦,卡洛斯的回答做到了,尽管我可能会按照你的建议继续整理 HTML ......只是为了确保内部标记没有其他任何东西。

以上是关于是否有用于 PHP 的宽松、宽松的 XML 解析器?的主要内容,如果未能解决你的问题,请参考以下文章

Java 是不是有一个好的 *strict* 日期解析器?

使用宽松字典映射列中的值

什么是宽松功能?

Mysql大家是用严格模式还是宽松模式

Erlang--proplists结构解析

常见的html面试题