猿问

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

这里建议有两种方法可以获取 DOMDocument 节点的外部 HTML:如何返回 DOMDocument 的外部 html?


我感兴趣的是为什么他们似乎以不同的方式对待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()


MMTTMM
浏览 119回答 1
1回答

呼唤远方

归根结底,这比上面的测试用例还要简单:<?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;那么问题来了,为什么在保存整个文档而不仅仅是一个特定的节点时,行为会有所不同?DomDocument::saveHtml通过查看PHP源代码,我们会发现它是使用单个节点还是整个文档进行检查。对于前者,调用该函数时,编码显式设置为 null。对于后者,使用函数,编码不作为此函数的参数包含在内。htmlNodeDumpFormatOutputhtmlDocDumpMemoryFormat这两个函数都来自 libxml2 库。查看该源,我们可以看到尝试检测文档编码,并在找不到文档编码时将其显式设置为ASCII / HTML。htmlDocDumpMemoryFormat这两个函数最终都调用htmlNodeListDumpOutput,并为其传递已确定的编码;null ( 不会导致编码 – 或 ASCII/HTML – 使用 HTML 实体进行编码。我的猜测是,对于文档片段或单个节点,编码被认为不如完整文档重要。
随时随地看视频慕课网APP
我要回答