I have this structure
<div >
<div id="wrap">
<div >
Content
</div>
</div>
</div>
I would like to remove the div with id wrap but keep the contentlike this
<div >
<div >
Content
</div>
</div>
I've tried a few regular expressions but withour sucess
$content = preg_replace('/<div[^>] id="[^>]*wrap[^>]*"[^>]*>.*?<\/div>/i', '', $content);
or
$content = preg_replace('/<div id="wrap">(. ?)<\/div>', '', $content);
CodePudding user response:
Modifying HTML through regex is bad idea and it leads to unexpected errors. You should better use DOM
api for this:
$s = '<div >
<div id="wrap">
<div >
Content 1
</div>
<div >
Content 2
</div>
<p id="ab12">Hello</p>
<img src="xy.jpg"/>
</div>
<p id="pqr123">Hello</p>
<img src="ab.jpg"/>
</div>';
$doc = new DOMDocument();
$doc->loadHTML($s, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
$nlist = $xpath->query("//div[@id='wrap']");
for($i=0; $i < $nlist->length; $i ) {
$node = $nlist->item($i);
for($j=0; $j < $node->childNodes->length; $j ) {
$child = $node->childNodes->item($j);
if ($child->nodeName != "#text") {
$node->parentNode->appendChild($child);
}
}
$node->parentNode->removeChild($node);
}
$doc->formatOutput = true;
$newHTML = $doc->saveHTML();
echo $newHTML;
Output:
<div >
<p id="pqr123">Hello</p>
<img src="ab.jpg">
<div >
Content 1
</div>
<div >
Content 2
</div>
<p id="ab12">Hello</p>
<img src="xy.jpg">
</div>
CodePudding user response:
If you need a quick and dirty solution, why not just removing the id? This would be fine if your CSS is targeting the ID not the nesting.
echo str_replace('id="wrap"', '', $html);
You can manipulate HTML very well with DOM. This is the preferred way you should choose.
$html = <<<'_HTML_'
<div >
<div id="wrap">
<div >
Content
</div>
</div>
</div>
_HTML_;
$doc = new DOMDocument();
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$wrap = $doc->getElementById('wrap');
$wrapContent = $wrap->firstElementChild->cloneNode(true);
$wrapParent = $wrap->parentNode;
$wrapParent->removeChild($wrap);
$wrapParent->appendChild($wrapContent);
$doc->formatOutput = true;
echo $doc->saveHTML();
gives
<div >
<div >
Content
</div>
</div>