简体   繁体   中英

DOMDocument replace nodeValue text with fragment

I would like to replace text within a DOMNode with an HTML element fragment.

For example, given this HTML string:

<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>

I would like to replace " dolor sit amet ", wrapping it with an HTML element.

Resulting in something like:

<p>Lorem ipsum <em>dolor sit amet</em>, consectetuer adipiscing elit.</p>

I am able to append a new fragment to the element with something like the following:

$doc = new DOMDocument();
$paragraph = $doc->appendChild($doc->createElement('p', 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'));
$fragment = $doc->createDocumentFragment();
$fragment->appendXML('<em>dolor sit amet</em>');
$paragraph->appendChild($fragment);

However, that adds a new element within the paragraph. I can't seem to replace the text within the paragraph with another HTML element, I can only append the element to the end.

I have also tried this approach:

$paragraph->nodeValue = str_replace($searchtext, $doc->saveXML($fragment), $paragraph->nodeValue);

However, on output that results in an escaped HTML element ( &lt;em&gt; etc..) in the paragraph value and not a proper HTML element.

Any ideas how to replace the text content or node value with an HTML element?

Thoughts appreciated!

There's no need to create a separate element, you can use preg_replace function to search for the particular pattern and replace it with your string, like this:

$str = "<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>";

$doc = new DomDocument();
$doc->loadHTML($str);
$paragraph = $doc->getElementsByTagName('p')->item(0);
$modified_string = preg_replace('/dolor sit amet/', '<em>dolor sit amet</em>', $paragraph->textContent);
echo $modified_string;

Output:

在此处输入图片说明

Here's the reference:

Edited:

$str = "<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p>";

$doc = new DomDocument();
$doc->loadHTML($str);
$paragraph = $doc->getElementsByTagName('p')->item(0);
$paragraph->nodeValue = preg_replace('/dolor sit amet/', '<em>dolor sit amet</em>', $paragraph->textContent);
$str = htmlspecialchars_decode($doc->saveHtml());
echo $str;

OK, after further testing, I actually found a solution that replaces the text content with a new valid HTML element within DOMDocument.

Sample code as follows:

$doc = new DOMDocument();
// Create sample paragraph element
$paragraph = $doc->appendChild($doc->createElement('p', 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.'));
// Create example replacement insert element
$element = $doc->createElement('em', 'dolor sit amet');
// Create element fragment to insert
$fragment = $doc->createDocumentFragment();
// Get new paragraph value
$new_value = str_replace('dolor sit amet', $doc->saveXML($element), $paragraph->nodeValue);
// Add new paragraph value as fragment
$fragment->appendXML('<p>' . $new_value . '</p>');
// Replace paragraph element with new valid fragment
$paragraph->parentNode->replaceChild($fragment, $paragraph);

Result:

<p>Lorem ipsum <em>dolor sit amet</em>, consectetuer adipiscing elit.</p>

Hopefully that helps future readers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM