PHP DOM Manipulation - DOMDocument

Example code, replace an iframe with a div

Note: this does not work for multiple iframes: See below for an alternative version

<?php
$dom = new DOMDocument();
// Options: do not add DOCTYPE, html or body tags
$dom->loadHTML($code, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$iframes = $dom->getElementsByTagName('iframe');

foreach ($iframes as $iframe) {

    // Get iframe tag html code
    // Example: <iframe src="https://example.com/foo.html"></iframe>
    $iframeHtml = $dom->saveHTML($iframe);

    // Prepare a new fragment as a replacement for the iframe
    $fragment = $dom->createDocumentFragment();
    $div = '<div data-foo="bar">No iframe anymore :-)</div>';
    $fragment->appendXML($div);

    // This would append the div after the iframe
    // $iframe->parentNode->appendChild($fragment);

    // Replace iframe with div
    $iframe->parentNode->replaceChild($fragment, $iframe);
}

// The following produced garbled special characters:
// $code = $dom->saveHTML();
$code = utf8_decode($dom->saveHTML($dom->documentElement));

Alternative with search and replace:

<?php
$dom = new DOMDocument();
// Options: do not add DOCTYPE, html or body tags
$dom->loadHTML($code, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$iframes = $dom->getElementsByTagName('iframe');

$replacements = [];

foreach ($iframes as $iframe) {

    $replacement = [];

    // Get iframe tag html code
    // Example: <iframe src="https://example.com/foo.html"></iframe>
    $iframeHtml = $dom->saveHTML($iframe);
    $replacement['search'] = $iframeHtml;

    $div = '<div data-foo="bar">No iframe anymore :-)</div>';
    $replacement['replace'] = $div;
    $replacements[] = $replacement;    
}

foreach ($replacements as $replacement) {
    $code = str_replace($replacement['search'], $replacement['replace'], $code);
}

 

Find by attribute

$html = '<a class="foo">bar</a>';

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

$finder = new DomXPath($dom);
$nodes = $finder->evaluate("//a[@class='foo']");

foreach ($nodes as $node) {
  var_dump($node->nodeValue);
}

// or
var_dump($finder->evaluate("//a[@class='foo']")->item(0)->nodeValue);