la_petite_kozel
la_petite_kozel

Reputation: 890

Unwanted paragraph when saving html in DOM

After manipulations with DOM element and saving it using $dom->saveHTML(); getting extra empty paragraph in my output, here is my code:

PHP:

$dom_str = "Phasellus eu arcu vest, <mark data-tooltip='tooltip'></mark> sodales dui."
$dom = new DOMDocument;
$dom->loadHTML($dom_str);
$dom_items = $dom->getElementsByTagName('mark'); // retrieving elements by tag

$dom_app = $dom->createElement('amp-script');
$dom_span = $dom->createElement('span');

$dom_app->appendChild($dom_span);

$mark_item = $dom_items->item(0);
$mark_item->appendChild($dom_app); // appending additional HTML
$output_dom = $dom->saveHTML(); // saving DOM       

$output .= '<div><p>'. $output_dom .'</p></div>';

return $output; 

Output:

<div>
<p></p> <! –– Unwanted paragraph ––>
<p>Phasellus eu arcu vest, <mark><amp-script><span></span></amp-script></mark> sodales dui</p>
</div>

Already tried $dom->loadHTML($dom_str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); but empty paragraph still stays.

Upvotes: 2

Views: 475

Answers (1)

Chris Haas
Chris Haas

Reputation: 55457

When calling loadHTML with a partial HTML snippet instead of a full HTML document, it is probably a good idea to pass both LIBXML_HTML_NOIMPLIED and LIBXML_HTML_NODEFDTD OR'd together as the second parameter, otherwise DOMDocument is going to start "fixing" things for you:

$dom->loadHTML($dom_str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

I also had to add libxml_use_internal_errors(true); to get the mark tag to work

With those two changes, and ignoring your string concatenation at the end, I get this:

$dom_str = "Phasellus eu arcu vest, <mark data-tooltip='tooltip'></mark> sodales dui.";
$dom = new DOMDocument;
libxml_use_internal_errors(true); // Enabled HTML5 tags
$dom->loadHTML($dom_str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Don't automatically create html/body/doctype tags
$dom_items = $dom->getElementsByTagName('mark'); // retrieving elements by tag

$dom_app = $dom->createElement('amp-script');
$dom_span = $dom->createElement('span');

$dom_app->appendChild($dom_span);

$mark_item = $dom_items->item(0);
$mark_item->appendChild($dom_app); // appending additional HTML
echo $dom->saveHTML(); // saving DOM

This outputs the following:

<p>Phasellus eu arcu vest, <mark data-tooltip="tooltip"><amp-script><span></span></amp-script></mark> sodales dui.</p>

Demo: https://3v4l.org/KRDKS

Upvotes: 1

Related Questions