Howdy_McGee Howdy_McGee - 4 months ago 11
PHP Question

Match All Elements With Background Colors

Here's the issue - in a TinyMCE I'm working with it's adding a

background-color
on a span wrapper instead of the parent element. I'm trying to search the content string and grab the
span
styles to put it on the parent element. I have HTML like this:

<h3><span style="background-color: #000000;">Hello World!</span></h3>


So I'm trying to match any
span
with a
background
or
background-color
and put that as a
style
onto its parent. I'm trying to work with DOMDocument but I'm not too familiar with it:

$html = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath = new DOMXPath( $htmlDOM );
$headers = $xpath->query( '//h1//span|//h2//span|//h3//span|//h4//span|//h5//span|//h6//span' );

foreach( $headers as $index => $element ) {
print_r( $element ); // The Header Element

if( $element->attributes->length ) {
foreach( $element->attributes as $asdf => $attr ) {
print_r( $attr ); // The Span Attributes ( style )
}
}
}


I get the actual style attribute with the above but I don't know how to assign it to the parent. I'm not sure if this is faster than
preg_match()
but I'm not familiar enough with regex. Any help / suggestions or tips would be appreciated!

Answer
$html       = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM    = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath      = new DOMXPath( $htmlDOM );
// Find `h*` having child `span` with `style` attribute    
$headers = $xpath->query( '//*[contains("h1|h2|h3|h4|h5|h6", name())  and span[@style]]');

foreach( $headers as $element) {
    // Find `span` element
    $span = $xpath->query('./span', $element)->item(0);
    // Move all attributes from `span` to `h*
    foreach($span->attributes as $attr)
       $element->setAttribute($attr->name, $attr->nodeValue);
    // Save value of `span`
    $value = $element->nodeValue;
    // Remove `span` 
    $span->parentNode->removeChild($span);
    // Set former `span` value as `h*` value
    $element->nodeValue = $value;
}

echo $htmlDOM->saveHTML();

demo

Comments