为什么这两个DOMDocument函数的行为不同?

问题描述 投票:1回答:1

这里有两种方法可以获取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&rsquo;s 27&rdquo; 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&rsquo;s 27&rdquo; Monitor is $200.</p>

[这两种方法都使用saveHTML(),但是由于某种原因,该函数将html实体保留在最终输出中,而直接使用节点上下文调用saveHTML()则不这样做。任何人都可以解释原因-最好使用某种权威参考?

php html domdocument html-entities
1个回答
1
投票

这比上面的测试用例还要简单:

saveHTML()

所以问题就变成了,为什么<?php $html = '<p>ACME&rsquo;s 27&rdquo; 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实体进行编码)。

我的猜测是,对于文档片段或单个节点,编码不如对整个文档重要。

© www.soinside.com 2019 - 2024. All rights reserved.