我有一堆类似 HTML 的旧文档。例如,它们看起来像 HTML,但具有不属于 HTML 一部分的附加组成标签

<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>

我需要解析这些文件。PHP 是唯一可用的工具。这些文档与格式良好的 XML 相差甚远。

我最初的想法是在 PHP DOMDocument 上使用 loadHTML 方法。然而,这些方法会阻塞 HTML 标签,并拒绝解析字符串/文件。

$oDom = new DomDocument();
$oDom->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
//gives us
DOMDocument::loadHTML() [function.loadHTML]: Tag pseud-template invalid in Entity, line: 1 occured in ....

我能想到的唯一解决方案是使用字符串替换函数对文件进行预处理,该函数将删除无效标签并将其替换为有效的 HTML 标签(可能是带有标签名称 id 的跨度)。

有更优雅的解决方案吗?一种让 DOMDocument 了解被视为有效的附加标签的方法?PHP 是否有不同的、强大的 HTML 解析类/对象?

(如果不明显,我不认为正则表达式是有效的解决方案)

更新:假标签中的信息是这里目标的一部分,因此像 Tidy 这样的东西不是一个选择。另外,我正在寻找一种能够为我完成一定程度(如果不是全部)格式良好清理的东西,这就是我首先寻找 DomDocument 的 loadHTML 方法的原因。

有帮助吗?

解决方案

您可以使用以下命令抑制警告 libxml_use_internal_errors, ,同时加载文档。例如。:

libxml_use_internal_errors(true);
$doc = new DomDocument();
$doc->loadHTML("<strong>This is an example of a <pseud-template>fake tag</pseud-template></strong>");
libxml_use_internal_errors(false);

如果由于某种原因您需要访问警告,请使用 libxml_get_errors

其他提示

我想知道是否通过传递“坏”HTML HTML 整洁 作为第一遍可能有帮助吗?可能值得一看,如果您可以使文档格式良好,也许您可​​以使用 DomDocument 将其作为常规 XML 文件加载。

@twan您不需要DTD即可用于解析自定义XML。只需使用 DOMDocument->load(), ,只要 XML 格式良好,它就可以读取。

一旦文件格式良好,您就可以开始查看 XML 解析器,在此之前您就可以了。Lok Alejo 说,你可以看看 HTML 整洁, ,但看起来这是特定于 HTML 的,我不知道它如何与您的自定义元素配合使用。

我不认为正则表达式是这里的有效解决方案

在你成熟之前,这可能是你唯一的选择。一旦文档到达该阶段,您就可以清楚地了解 DOM 函数了。

看一下 PHP Fit 端口中的解析器。代码很干净,最初是为了加载Word保存的脏HTML而设计的。它被配置为拉出表,但可以很容易地进行调整。

您可以在这里查看来源:http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/Parser.phps

单元测试将向您展示如何使用它:http://gerd.exit0.net/pat/PHPFIT/PHPFIT-0.1.0/test/parser.phps

我对这个问题的快速而肮脏的解决方案是运行一个循环,将我的自定义标签列表与正则表达式相匹配。正则表达式不会捕获其中包含另一个内部自定义标签的标签。

当存在匹配时,将调用处理该标记的函数并返回“已处理的 HTML”。如果该自定义标记位于另一个自定义标记内,则由于插入了实际 HTML 来代替子标记,因此父标记将变得无子标记,并且它将由正则表达式进行匹配并在循环的下一次迭代中进行处理。

当没有要匹配的无子自定义标签时,循环结束。总的来说,它是迭代的(一个 while 循环)而不是递归的。

@艾伦·斯托姆

您对我的其他答案的评论让我思考:

当您使用 DOMDocument 加载 HTML 文件时,它似乎会进行一定程度的清理:格式良好,但要求所有标签都是合法的 HTML 标签。我正在寻找可以实现前者但不能实现后者的东西。(艾伦·斯托姆饰演)

对标签运行正则表达式(抱歉!),当它发现一个不是有效的 HTML 元素时,将其替换为您知道任何文档中都不存在的有效元素(blink 我想到了...),并给它一个带有非法元素名称的属性值,以便您可以稍后将其切换回来。例如:

$code = str_replace("<pseudo-tag>", "<blink rel=\"pseudo-tag\">", $code);
// and then back again...
$code = preg_replace('<blink rel="(.*?)">', '<\1>', $code);

显然该代码行不通,但是您明白总体思路了吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top