我有一个可怕的算法,“删除节点”,将其内部内容移动到其父节点(见下文)……但我认为有可能使用
DOMDocumentFragment(而不是使用saveXML / loadXML)开发更好的算法.
@H_404_24@下面的算法灵感来自renameNode().
/** * Move the content of the $from node to its parent node. * Conditions: parent not a document root,$from not a text node. * @param DOMElement $from to be removed,preserving its contents. * @return true if changed,false if not. */ function moveInner($from) { $to = $from->parentNode; if ($from->nodeType==1 && $to->parentNode->nodeType==1) { // Scans $from,and record information: $lst = array(); // to avoid "scan bugs" of DomNodeList iterator foreach ($to->childNodes as $e) $lst[] = array($e); for($i=0; $i<count($lst); $i++) if ($lst[$i][0]->nodeType==1 && $from->isSameNode($lst[$i][0])) { $lst[$i][1] = array(); foreach ($lst[$i][0]->childNodes as $e) $lst[$i][1][] = $e; } // Build $newTo (rebuilds the parent node): $newTo = $from->ownerDocument->createElement($to->nodeName); foreach ($to->attributes as $a) { $newTo->setAttribute($a->nodeName,$a->nodeValue); } foreach ($lst as $r) { if (count($r)==1) $newTo->appendChild($r[0]); else foreach ($r[1] as $e) $newTo->appendChild($e); } // Replaces it: $to->parentNode->replaceChild($newTo,$to); return true; } else return false; }
例
INPUT
<html id="root"> <p id="p1"><i>Title</i></p> <p id="p2"><b id="b1">Rosangela<sup>1</sup>,Maria<sup>2</sup></b>,<b>Eduardo<sup>4</sup></b> </p> </html>
moveInner的输出($dom-> getElementById(‘p1’))
... <p id="p1">Title</p> ...
moveInner的输出($dom-> getElementById(‘b1’))
... <p id="p2">Rosangela<sup>1</sup>,Maria<sup>2</sup>,<b>Eduardo<sup>4</sup></b> </p> ...
首次使用后,moveInner($dom-> getElementById(‘root’))或moveInner($dom-> getElementById(‘p1’))没有变化.
PS:就像一个“TRIM TAG”功能.