I’m trying to replace all tags with tags using DOMDocument in PHP and almost all my tests passed. I’m sure there are other scenarios I’m forgetting, but for now, I’m missing just one:
ORIGINAL:
<p><font color="#ff0000">BEFORE <font color="#00ff00">BEFORE <font color="#0000ff">VAL</font> AFTER</font> AFTER</font></p>
RESULT:
<p><span style="color: #ff0000">BEFORE BEFORE VAL AFTER AFTER</span></p>
The PHP code for this:
$html = '<p><font color="#ff0000">BEFORE <font color="#00ff00">BEFORE <font color="#0000ff">VAL</font> AFTER</font> AFTER</font></p>';
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach($dom->getElementsByTagName('font') as $node) {
$font_nodes[] = $node;
}
//$font_nodes = array_reverse($font_nodes);
foreach($font_nodes as $font) {
$a_style = array_filter(explode(';', $font->getAttribute('style')));
if($a_color = $font->getAttribute('color')) {
$a_style[] = 'color: '.$a_color;
}
$span = $dom->createElement('span', $font->nodeValue);
$span->setAttribute('style', implode('; ', $a_style));
$font->parentNode->replaceChild($span, $font);
}
echo preg_replace("#(<!DOCTYPE.+|<\/?html>|<\/?body>)#", '', $dom->saveHTML());
I thought that getElementsByTagName was the culprit since it was loading the nodes in order, so I tried to start from the deepest tag by reversing the array, but that didn’t work so the line is commented.
P.S: In case you’re wondering why the first loop is needed to save all the nodes and loop them again, please read this: http://robrosenbaum.com/php/domnodelist-gotchas/
This works. I tested it. 🙂
Replace the line:
With this: