这里有两种方法可以获取DOMDocument节点的外部HTML:How to return outer html of DOMDocument?
我对他们为什么似乎对HTML实体区别对待感兴趣。
示例:
function outerHTML($node) {
$doc = new DOMDocument();
$doc->appendChild($doc->importNode($node, true));
return $doc->saveHTML();
}
$html = '<p>ACME’s 27” Monitor is $200.</p>';
$dom = new DOMDocument();
@$dom->loadHTML($html);
$el = $dom->getElementsByTagname('p')->item(0);
echo $el->ownerDocument->saveHtml($el) . PHP_EOL;
echo outerHTML($el) . PHP_EOL;
输出:
<p>ACME’s 27” Monitor is $200.</p> <p>ACME’s 27” Monitor is $200.</p>
[这两种方法都使用saveHTML()
,但是由于某种原因,该函数将html实体保留在最终输出中,而直接使用节点上下文调用saveHTML()
则不这样做。任何人都可以解释原因-最好使用某种权威参考?
这比上面的测试用例还要简单:
saveHTML()
所以问题就变成了,为什么<?php
$html = '<p>ACME’s 27” Monitor is $200.</p>';
$dom = new DOMDocument();
@$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
echo $dom->saveHtml($dom->documentElement) . PHP_EOL;
echo $dom->saveHtml() . PHP_EOL;
在保存整个文档而不是仅保存特定节点时表现出不同?
[偷看PHP源代码,我们发现DomDocument::saveHtml
是使用单个节点还是整个文档。对于前者,将使用显式设置为null的编码来调用a check函数。对于后者,使用htmlNodeDumpFormatOutput
函数,该函数的参数不包括编码。
这两个函数都来自libxml2库。查看that源,我们可以看到htmlDocDumpMemoryFormat
htmlDocDumpMemoryFormat
,如果找不到,则将其显式设置为ASCII / HTML。
两个函数最终都调用tries to detect the document encoding,并将确定的编码传递给它;要么为null(不进行编码),要么为ASCII / HTML(使用HTML实体进行编码)。
我的猜测是,对于文档片段或单个节点,编码不如对整个文档重要。