Reputation: 39270
Is there a way to do this? I would like to replace one element with another but somehow it isn't possible in PHP. Got the following code (the $content is valid html5 in my real code but took off some stuff to make the code shorter.):
$content='<!DOCTYPE html>
<content></content>
</html>';
$with='<img class="fullsize" src="/slide-01.jpg" />';
function replaceCustom($content,$with) {
@$document = DOMDocument::loadHTML($content);
$source = $document->getElementsByTagName("content")->item(0);
if(!$source){
return $content;
}
$fragment = $document->createDocumentFragment();
$document->validate();
$fragment->appendXML($with);
$source->parentNode->replaceChild($fragment, $source);
$document->formatOutput = TRUE;
$content = $document->saveHTML();
return $content;
}
echo replaceCustom($content,$with);
If I replace the <img class="fullsize" src="/slide-01.jpg" />
with <img class="fullsize" src="/slide-01.jpg">
then the content tag gets replaced with an empty string. Even though the img without closing tag is perfectly valid html it won't work because PHP only seems to support xml. All example code I've seen make use of the appendXML to create a documentFragment from a string but there is no HTML equivalent.
Is there a way to do this so it won't fail with valid HTML but invalid XML?
Upvotes: 0
Views: 1747
Reputation: 70480
DOMDocumentFragment::appendXML
indead requires XML in my version (5.4.20, libxml2 Version 2.8.0). You have mainly 2 options:
<img />
.If you want to stick to the standards, you will have to create a temporary DOMDocument with a dummy root and then loop through the child nodes of the root of your XML data to append them.
$tempDoc = new DOMDocument();
$tempDoc->loadHTML('<html><body>'.$with.'</body></html>');
$body = $tempDoc->getElementsByTagName('body')->item(0);
foreach($body->childNodes as $node){
$newNode = $document->importNode($node, true);
$source->parentNode->insertBefore($newNode,$source);
}
$source->parentNode->removeChild($source);
Upvotes: 2