HTMLラッパーなしでDOMDocumentのHTMLを保存するにはどうすればいいですか?質問する

HTMLラッパーなしでDOMDocumentのHTMLを保存するにはどうすればいいですか?質問する

私は以下の関数で、XML、HTMLを追加せずにDOMDocumentを出力するのに苦労しています。そしてpコンテンツの出力前にタグラッパーを使用します。提案された修正方法:

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

コンテンツ内にブロック レベル要素が含まれていない場合にのみ機能します。ただし、以下の h1 要素の例のようにブロック レベル要素が含まれている場合、saveXML からの出力結果は次のように切り捨てられます...

<p>よろしければ</p>

回避策としてこの投稿が紹介されましたが、このソリューションにそれを実装する方法がわかりません (以下のコメントアウトされた試行を参照してください)。

助言がありますか?

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;
}

ベストアンサー1

これらの答えはすべて間違っているPHP 5.4とLibxml 2.6以降ではloadHTML$optionLibxml にコンテンツの解析方法を指示するパラメータが追加されました。

したがって、これらのオプションを使用してHTMLを読み込むと

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

行う場合、 も も もsaveHTML()ありません。doctype<html><body>

LIBXML_HTML_NOIMPLIED暗黙の html/body 要素の自動追加をオフにすると、LIBXML_HTML_NODEFDTDデフォルトの doctype が見つからない場合にそれが追加されなくなります。

Libxmlパラメータに関する完全なドキュメントはここ

(loadHTMLドキュメントでは Libxml 2.6 が必要であると記載されていますが、LIBXML_HTML_NODEFDTDLibxml 2.7.8 でのみ使用可能であり、LIBXML_HTML_NOIMPLIEDLibxml 2.7.7 でも使用可能です)

おすすめ記事