Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP DomNode->insertBefore()

I am trying to insert nodes in my html string. My goal is to insert an element before each h2 tag.

For that, I am using:

$htmlString = "<h2>some html</h2>";

$DOM = new DOMDocument();
$DOM->loadHTML($htmlString);

$itemTitles = $DOM->getElementsByTagName('h2');

for($i = 0; $i < $itemTitles->length; $i ++)
{
    $helpNavigatorContents[] = $itemTitles->item($i)->nodeValue;
    $textBefore = new DOMNode(
        '<a name="'.$itemTitles->item($i)->nodeValue.'"></a>'
    );
    $itemTitles->item($i)->parentNode->insertBefore(
        $textBefore, 
        $itemTitles->item($i)
    );
}

$htmlString = $DOM->saveHTML($DOM);

And here I have a problem with the $textBefore. When I declare the $textBefore as a DOMText, I can insert the text before the node but when I try this with DOMNode, then I am getting the following error (Demo):

Warning: DOMNode::insertBefore(): Couldn't fetch DOMNode

like image 833
Milos Cuculovic Avatar asked Jan 16 '23 11:01

Milos Cuculovic


1 Answers

The code doesn't make any sense. DOMNode does not have a constructor. It is not supposed to be created at all. You are supposed to create specific node types through DOMDocument to have them associated with the Document.

Assuming you want to prepend all the H2 element with an anchor, this is how to do it:

libxml_use_internal_errors(true);
$DOM = new DOMDocument();
$DOM->loadHTML($htmlString);
$DOM->preserveWhiteSpace = false;

foreach ($DOM->getElementsByTagName('h2') as $h2) {
    $a = $DOM->createElement('a');
    $a->setAttribute('name', $h2->nodeValue);
    $h2->parentNode->insertBefore($a, $h2);
}
$DOM->formatOutput = true;
echo $DOM->saveHTML();

Demo http://codepad.org/N0dPcLwT

To wrap the H2 elements into the A element, simply do the same and add

$a->appendChild($h2);

Demo http://codepad.org/w7Hi0Bmz

like image 189
Gordon Avatar answered Jan 25 '23 17:01

Gordon