7

I'm trying to change all <P> tags in a document to <DIV>. This is what I've come up with, but it doesn't seem to work:

$dom = new DOMDocument;
$dom->loadHTML($htmlfile_data);

foreach( $dom->getElementsByTagName("p") as $pnode ) {
    $divnode->createElement("div");
    $divnode->nodeValue = $pnode->nodeValue;
    $pnode->appendChild($divnode);
    $pnode->parentNode->removeChild($pnode);
}

This is the result I want:

Before:

<p>Some text here</p>

After:

<div>Some text here</div>
RichardTheKiwi
  • 105,798
  • 26
  • 196
  • 262
James Nine
  • 2,548
  • 10
  • 36
  • 53

2 Answers2

9

You are appending the div to your p which results in <p><div></div></p>, removing the p will remove everything.
Additionally $divnode->createElement() won't work when $divnode isn't initialized.

Try instead to use the DOMDocument::replaceChild() (the divs position in the dom will be the same as the ps).

foreach( $dom->getElementsByTagName("p") as $pnode ) {
    $divnode = $dom->createElement("div", $pnode->nodeValue);
    $dom->replaceChild($divnode, $pnode);
}
Samuel Herzog
  • 3,561
  • 1
  • 22
  • 21
  • 1
    **One note:** if `$pnode->nodeValue` is not a plain text, but has extra nodes in it, only text will be left (html will be stripped). – i-- Jun 28 '13 at 17:36
  • You can't just replace items while iterating since the index changes and you end up with weird results. – Sanne Mar 17 '14 at 14:51
  • 2
    guess what: I actually tested this at the time I answered it. So in case you use a recent PHP version foreach can handle the manipulation of the index. – Samuel Herzog Mar 26 '14 at 15:09
  • as Sanne said their will be an error for multiple items. Check this answer https://stackoverflow.com/questions/12018747/replace-tag-in-html-with-domdocument/12018817#12018817 – fearis Dec 07 '15 at 11:07
0

Enhanced function from this answer

function changeTagName( $node, $name ) {
    $childnodes = array();
    foreach ( $node->childNodes as $child ) {
        $childnodes[] = $child;
    }
    $newnode = $node->ownerDocument->createElement( $name );
    foreach ( $childnodes as $child ){
        $child2 = $node->ownerDocument->importNode( $child, true );
        $newnode->appendChild($child2);
    }
    if ( $node->hasAttributes() ) {
        foreach ( $node->attributes as $attr ) {
            $attrName = $attr->nodeName;
            $attrValue = $attr->nodeValue;
            $newnode->setAttribute($attrName, $attrValue);
        }
    }
    $node->parentNode->replaceChild( $newnode, $node );
    return $newnode;
}
Community
  • 1
  • 1
elvismdev
  • 1,027
  • 11
  • 21