PHP DOMDocument 添加了额外的标签

Posted

技术标签:

【中文标题】PHP DOMDocument 添加了额外的标签【英文标题】:PHP DOMDocument adds extra tags 【发布时间】:2011-06-15 14:05:49 【问题描述】:

我正在尝试解析文档并获取所有图像标签并更改源以获取不同的内容。

$domDocument = new DOMDocument();

$domDocument->loadhtml($text);

$imageNodeList = $domDocument->getElementsByTagName('img');

foreach ($imageNodeList as $Image) 
  $Image->setAttribute('src', 'lalala');
  $domDocument->saveHTML($Image);


$text = $domDocument->saveHTML();

$text 最初看起来像这样:

<p>Hi, this is a test, here is an image<img src="http://example.com/beer.jpg"   /> Because I like Beer!</p>

这是$text的输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>Hi, this is a test, here is an image<img src="lalala"  > Because I like Beer!</p></body></html>

我得到了一堆我并不真正需要的额外标签(HTML、正文和顶部的评论)。有什么方法可以设置DOMDocument 以避免添加这些额外的标签?

【问题讨论】:

【参考方案1】:

如果您要保存为 HTML,您必须期望创建一个有效的 HTML 文档!

还有另一个选项:DOMDocument::saveXML 有一个可选参数,允许您访问特定元素的 XML 内容:

$el = $domDocument->getElementsByTagName('p')->item(0);
$text = $domDocument->saveXML($el);

这假定您的内容只有一个 p 元素。

【讨论】:

根据文档中使用的元素,使用 saveXML() 检索 HTML 源代码并不总是一个好主意。创建的 XML 将使用所有没有内容的元素的简写,这会损坏 HTML 文档(例如&lt;script src="some.js"/&gt;)。您需要解析结果并更正它或使用 XSLT 对其进行转换以获得有效的 HTML 文档。【参考方案2】:

如果你想破解,这就是我设法解决这个烦恼的方法。将字符串加载为 XML 并将其保存为 HTML。 :)

【讨论】:

【参考方案3】:

不幸的是,DomDocument 是迟钝的,不会让你这样做。试试这个:

$text = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $domDocument->saveHTML()));

【讨论】:

它应该是:$text = preg_replace('/^+?>/', '', str_replace(array('', '', '', ''), array('', '', '', ''), $domDocument->saveHTML())); preg_replace,真的吗?【参考方案4】:

你可以使用http://beerpla.net/projects/smartdomdocument-a-smarter-php-domdocument-class/:

DOMDocument 有一个设计非常糟糕的“功能”,如果您正在加载的 HTML 代码不包含和标签,它会自动添加它们(是的,没有标志可以关闭此行为)。

因此,当您调用 $doc->saveHTML() 时,您新保存的内容现在包含和 DOCTYPE。尝试使用代码片段时不是很方便(XML 有类似的问题)。

SmartDOMDocument 包含一个名为 saveHTMLExact() 的新函数,它完全符合您的要求 - 它保存 HTML 而不会添加 DOMDocument 所做的额外垃圾。

【讨论】:

【参考方案5】:

您只需向loadHTML() 方法添加2 个标志:LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD。即

$domDocument->loadHTML($text, LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD);

见IDEONE demo:

$text = '<p>Hi, this is a test, here is an image<img src="http://example.com/beer.jpg"   /> Because I like Beer!</p>';
$domDocument = new DOMDocument;
$domDocument->loadHTML($text, LIBXML_HTML_NOIMPLIED|LIBXML_HTML_NODEFDTD);
$imageNodeList = $domDocument->getElementsByTagName('img');

foreach ($imageNodeList as $Image) 
      $Image->setAttribute('src', 'lalala');
      $domDocument->saveHTML($Image);


$text = $domDocument->saveHTML();
echo $text;

输出:

<p>Hi, this is a test, here is an image<img src="lalala"  > Because I like Beer!</p>

【讨论】:

对我来说,这只是将所有 html 从那里剥离。我的段落也不见了。 @Mike:这是不可能的,因为代码不会删除任何内容。也许您拥有的 HTML 并不完全有效。在使用 $domDocument = new DOMDocument; 初始化 DOMDocument 之前尝试添加 libxml_use_internal_errors(true); @WiktorStribiżew 我正在使用它从文本字段中剥离脚本标签,如下所示:***.com/questions/7130867/…

以上是关于PHP DOMDocument 添加了额外的标签的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP DOMDocument 更改标签属性值

PHP DOMDocument获取标签的属性

使用 PHP DOMDocument 解析脏 html 代码时遇到困难

如何使用 DOMDocument 编写 XML 自闭标签

DOMDocument & XPath - 每个节点的 HTML 标签

PHP domdocument 插入符号