Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to use PHP DOM to replace node text without changing child nodes

I am trying to use the dom object to simplify the implementation of a glossary tooltip. What I need to do is to replace a text element in a paragraph, but NOT in an anchor tag that may be embedded in the paragraph.

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementByTagName("p");
foreach ($nodes as $node) {
  $node->nodeValue = str_replace("tag","element",$node->nodeValue);
}
echo $document->saveHTML();

I get:

'...<p>Replace this element not this element</p>...'

I want:

'...<p>Replace this element not this <a href="#">tag</a></p>...'

How do I implement this such that only the parent node text is changed and the child node (a tag) is not changed?

like image 735
user1605657 Avatar asked Oct 21 '25 21:10

user1605657


1 Answers

Try this:

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementsByTagName("p");

foreach ($nodes as $node) {
    while( $node->hasChildNodes() ) {
        $node = $node->childNodes->item(0);
    }
    $node->nodeValue = str_replace("tag","element",$node->nodeValue);
}
echo $document->saveHTML();

Hope this helps.

UPDATE To answer @paul's question in the comments below, you can create

$html = '<p>Replace this tag not this <a href="#">tag</a></p>';
$document = new DOMDocument();
$document->loadHTML($html);
$document->preserveWhiteSpace = false;
$document->validateOnParse = true;

$nodes = $document->getElementsByTagName("p");

//create the element which should replace the text in the original string
$elem = $document->createElement( 'dfn', 'tag' );
$attr = $document->createAttribute('title');
$attr->value = 'element';
$elem->appendChild( $attr );

foreach ($nodes as $node) {
    while( $node->hasChildNodes() ) {
        $node = $node->childNodes->item(0);
    }
    //dump the new string here, which replaces the source string
    $node->nodeValue = str_replace("tag",$document->saveHTML($elem),$node->nodeValue);
}
echo $document->saveHTML();
like image 132
web-nomad Avatar answered Oct 24 '25 11:10

web-nomad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!