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:
这是问题 - 在TinyMCE中我正在使用它在跨度包装器而不是父元素上添加背景颜色。我正在尝试搜索内容字符串并获取span样式以将其放在父元素上。我有像这样的HTML:
<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:
所以我试图将任何跨度与背景或背景颜色匹配,并将其作为样式放在其父级上。我正在尝试使用DOMDocument,但我不太熟悉它:
$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!
我得到了上面的实际样式属性,但我不知道如何将它分配给父。我不确定这是否比preg_match()快,但我对正则表达式不够熟悉。任何帮助/建议或提示将不胜感激!
3 个解决方案
#1
2
$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();
#2
0
A dom solution would be better. But if you want to use a regex solution, you could use:
一个dom解决方案会更好。但是如果你想使用正则表达式解决方案,你可以使用:
$html = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$html_new = preg_replace("@(<h\d[^>]*)(>)(\s*<span[^<>]+)(style\s*=\s*["'][^"']*["'])[^>]*>([^<>]+)</span>@", "$1 $4$2$5", $html);
It will only work on h1
etc. elements, and if the span
element will follow directely and has no child elements.
它只适用于h1等元素,如果span元素将直接跟随并且没有子元素。
#3
0
Thanks to /u/splash58's answer it pushed me in the right direction:
感谢/ u / splash58的回答,它促使我朝着正确的方向前进:
$html = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath = new DOMXPath( $htmlDOM );
$elements = $xpath->query( '//h1//span|//h2//span|//h3//span|//h4//span|//h5//span|//h6//span' );
if( $elements->length ) {
foreach( $elements as $span ) {
$span_style = $span->getAttribute( 'style' );
if( false !== strpos( $span_style, 'background' ) ) {
$parent_style = $span->parentNode->getAttribute( 'style' );
$parent_style = rtrim( $parent_style, ';' );
$span_style = rtrim( $span_style, ';' );
$new_style = "{$parent_style}; {$span_style};";
$parent_style = $span->parentNode->setAttribute( 'style', $new_style );
$span->parentNode->nodeValue = $span->nodeValue;
}
}
}
echo $htmlDOM->saveHTML();
One thing I'm not certain on is why the span gets removed when I didn't specifically remove it. It seems to happen after I assign the spans nodeValue
to the parent. If anyone has an idea on why this might be or clarification please comment below and let me know!
我不确定的一件事是,当我没有特别删除它时,为什么跨度被删除。这似乎发生在我将跨度nodeValue分配给父节点之后。如果有人知道为什么会这样或澄清,请在下面评论并告诉我!
#1
2
$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();
#2
0
A dom solution would be better. But if you want to use a regex solution, you could use:
一个dom解决方案会更好。但是如果你想使用正则表达式解决方案,你可以使用:
$html = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$html_new = preg_replace("@(<h\d[^>]*)(>)(\s*<span[^<>]+)(style\s*=\s*["'][^"']*["'])[^>]*>([^<>]+)</span>@", "$1 $4$2$5", $html);
It will only work on h1
etc. elements, and if the span
element will follow directely and has no child elements.
它只适用于h1等元素,如果span元素将直接跟随并且没有子元素。
#3
0
Thanks to /u/splash58's answer it pushed me in the right direction:
感谢/ u / splash58的回答,它促使我朝着正确的方向前进:
$html = '<h3><span style="background-color: #000000;">Hello World!</span></h3>';
$htmlDOM = new DOMDocument();
$htmlDOM->loadHTML( $html );
$xpath = new DOMXPath( $htmlDOM );
$elements = $xpath->query( '//h1//span|//h2//span|//h3//span|//h4//span|//h5//span|//h6//span' );
if( $elements->length ) {
foreach( $elements as $span ) {
$span_style = $span->getAttribute( 'style' );
if( false !== strpos( $span_style, 'background' ) ) {
$parent_style = $span->parentNode->getAttribute( 'style' );
$parent_style = rtrim( $parent_style, ';' );
$span_style = rtrim( $span_style, ';' );
$new_style = "{$parent_style}; {$span_style};";
$parent_style = $span->parentNode->setAttribute( 'style', $new_style );
$span->parentNode->nodeValue = $span->nodeValue;
}
}
}
echo $htmlDOM->saveHTML();
One thing I'm not certain on is why the span gets removed when I didn't specifically remove it. It seems to happen after I assign the spans nodeValue
to the parent. If anyone has an idea on why this might be or clarification please comment below and let me know!
我不确定的一件事是,当我没有特别删除它时,为什么跨度被删除。这似乎发生在我将跨度nodeValue分配给父节点之后。如果有人知道为什么会这样或澄清,请在下面评论并告诉我!