我是下面的函数,我正在努力输出 DOMDocument 而不在内容输出之前附加 XML、HTML、body 和 p 标记包装器。建议的修复:

$postarray['post_content'] = $d->saveXML($d->getElementsByTagName('p')->item(0));

仅当内容中没有块级元素时才有效。但是,当它这样做时,如下面的带有 h1 元素的示例所示,来自 saveXML 的结果输出将被截断为...



有人指出这篇文章是一种可能的解决方法,但我无法理解如何将其实现到此解决方案中(请参阅下面注释掉的尝试)。

有什么建议么?
function rseo_decorate_keyword($postarray) {
    global $post;
    $keyword = "Jasmine Tea"
    $content = "If you like <h1>jasmine tea</h1> you will really like it with Jasmine Tea flavors. This is the last ocurrence of the phrase jasmine tea within the content. If there are other instances of the keyword jasmine tea within the text what happens to jasmine tea."
    $d = new DOMDocument();
    @$d->loadHTML($content);
    $x = new DOMXpath($d);
    $count = $x->evaluate("count(//text()[contains(translate(., 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz'), '$keyword') and (ancestor::b or ancestor::strong)])");
    if ($count > 0) return $postarray;
    $nodes = $x->query("//text()[contains(translate(., 'ABCDEFGHJIKLMNOPQRSTUVWXYZ', 'abcdefghjiklmnopqrstuvwxyz'), '$keyword') and not(ancestor::h1) and not(ancestor::h2) and not(ancestor::h3) and not(ancestor::h4) and not(ancestor::h5) and not(ancestor::h6) and not(ancestor::b) and not(ancestor::strong)]");
    if ($nodes && $nodes->length) {
        $node = $nodes->item(0);
        // Split just before the keyword
        $keynode = $node->splitText(strpos($node->textContent, $keyword));
        // Split after the keyword
        $node->nextSibling->splitText(strlen($keyword));
        // Replace keyword with <b>keyword</b>
        $replacement = $d->createElement('strong', $keynode->textContent);
        $keynode->parentNode->replaceChild($replacement, $keynode);
    }
$postarray['post_content'] = $d->saveXML($d->getElementsByTagName('p')->item(0));
//  $postarray['post_content'] = $d->saveXML($d->getElementsByTagName('body')->item(1));
//  $postarray['post_content'] = $d->saveXML($d->getElementsByTagName('body')->childNodes);
return $postarray;
}

最佳答案

所有这些答案现在都是错误的,因为从 PHP 5.4 和 Libxml 2.6 开始, loadHTML 现在有一个 $option 参数,它指示 Libxml 应该如何解析内容。

因此,如果我们使用这些选项加载 HTML

$html->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

执行 saveHTML() 时,将没有 doctype<html><body>



关于 Libxml 参数的完整文档是 here

(请注意,loadHTML 文档说需要 Libxml 2.6,但 LIBXML_HTML_NODEFDTD 仅在 Libxml 2.7.8 中可用,LIBXML_HTML_NOIMPLIED 在 Lib7xml 27 中可用)。

关于php - 如何在没有 HTML 包装器的情况下保存 DOMDocument 的 HTML?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4879946/

10-13 09:48