问题
Given this markup
<badtag>
This is the title and <em>really</em> needs help
<badtag>
I need to remove the wrapper, but do it without losing the tag, which is what happens if I simply do something like:
dom->createTextNode(currentNode->nodeValue)
I've tried the following, but it's not quite working and I want to make sure I'm on the right track and not missing an easier way. I do note that I need to add iteration when I hit a tag in the switch statement (rather than #text) so that I get the contents of the tag (such as with the tag).
$l = $origElement->childNodes->length;
$new = [];
for ($i = 0; $i < $l; ++$i) {
$child = $origElement->childNodes->item($i);
switch ($child->nodeName) {
case '#text':
$new[] = $dom->createTextNode($origElement->textContent);
break;
default:
$new[] = $child;
break;
}
}
foreach ($new as $struct) {
$parentNode->insertBefore($struct, $origElement);
}
$origElement->parentNode->removeChild($origElement);
回答1:
I've created something which creates a clone of the content of the node you want to remove. It didn't seem to like just moving the nodes, and when I use cloneNode
instead, the new version seemed a lot cleaner.
<?php
error_reporting ( E_ALL );
ini_set ( 'display_errors', 1 );
$xml = <<<EOB
<DATA>
<badtag>
This is the title and <em>really</em> needs help
</badtag>
</DATA>
EOB;
$dom = new DOMDocument();
$dom->loadXML($xml);
$origElement = $dom->getElementsByTagName("badtag")[0];
$newParent = $origElement->parentNode;
foreach ( $origElement->childNodes as $child ){
$newParent->insertBefore($child->cloneNode(true), $origElement);
}
$newParent->removeChild($origElement);
echo $dom->saveXML();
For the small sample I've used, the output is...
<?xml version="1.0"?>
<DATA>
This is the title and <em>really</em> needs help
</DATA>
来源:https://stackoverflow.com/questions/46774820/php-dom-how-to-remove-wrapping-tags-when-children-contain-tags-and-text-nodes